BondingCurveMath

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "BondingCurveMath.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library BondingCurveMath {

    uint256 public constant BASIS_POINTS = 10000;
    uint256 public constant PRECISION = 1e18;
    uint256 public constant MAX_SUPPLY = 1e15;

    error BondingCurve__InvalidParameters();
    error BondingCurve__InsufficientSupply();
    error BondingCurve__PriceCalculationFailed();
    error BondingCurve__Overflow();

    enum CurveType {
        LINEAR,
        EXPONENTIAL,
        LOGARITHMIC,
        SQUARE_ROOT,
        QUADRATIC
    }

    struct CurveConfig {
        CurveType curveType;
        uint256 a;
        uint256 b;
        uint256 c;
        uint256 startPrice;
        uint256 targetPrice;
        uint256 maxSupply;
    }

    function calculatePrice(
        CurveConfig memory config,
        uint256 currentSupply
    ) internal pure returns (uint256 price) {
        if (currentSupply > config.maxSupply) revert BondingCurve__InsufficientSupply();

        if (config.curveType == CurveType.LINEAR) {
            price = _calculateLinearPrice(config, currentSupply);
        } else if (config.curveType == CurveType.EXPONENTIAL) {
            price = _calculateExponentialPrice(config, currentSupply);
        } else if (config.curveType == CurveType.LOGARITHMIC) {
            price = _calculateLogarithmicPrice(config, currentSupply);
        } else if (config.curveType == CurveType.SQUARE_ROOT) {
            price = _calculateSquareRootPrice(config, currentSupply);
        } else if (config.curveType == CurveType.QUADRATIC) {
            price = _calculateQuadraticPrice(config, currentSupply);
        } else {
            revert BondingCurve__InvalidParameters();
        }

        if (price == 0) revert BondingCurve__PriceCalculationFailed();
    }

    function calculateTokensOut(
        CurveConfig memory config,
        uint256 currentSupply,
        uint256 ethAmount
    ) internal pure returns (uint256 tokensOut) {
        if (ethAmount == 0) return 0;

        uint256 low = 0;
        uint256 high = config.maxSupply - currentSupply;
        uint256 tolerance = PRECISION / 1000;

        while (high - low > tolerance && high > low) {
            uint256 mid = (low + high) / 2;
            uint256 cost = calculateCost(config, currentSupply, mid);

            if (cost < ethAmount) {
                low = mid;
            } else if (cost > ethAmount) {
                high = mid;
            } else {
                return mid;
            }
        }

        tokensOut = low;
    }

    function calculateCost(
        CurveConfig memory config,
        uint256 currentSupply,
        uint256 tokenAmount
    ) internal pure returns (uint256 cost) {
        if (tokenAmount == 0) return 0;
        if (currentSupply + tokenAmount > config.maxSupply) {
            revert BondingCurve__InsufficientSupply();
        }

        cost = _calculateIntegral(config, currentSupply, currentSupply + tokenAmount);
    }

    function calculateETHOut(
        CurveConfig memory config,
        uint256 currentSupply,
        uint256 tokenAmount
    ) internal pure returns (uint256 ethOut) {
        if (tokenAmount == 0) return 0;
        if (tokenAmount > currentSupply) revert BondingCurve__InsufficientSupply();

        ethOut = _calculateIntegral(config, currentSupply - tokenAmount, currentSupply);
    }

    function calculateMarketCap(
        CurveConfig memory config,
        uint256 currentSupply
    ) internal pure returns (uint256 marketCap) {
        uint256 currentPrice = calculatePrice(config, currentSupply);
        
        if (currentSupply > type(uint256).max / currentPrice) {
            revert BondingCurve__Overflow();
        }
        
        marketCap = (currentSupply * currentPrice) / PRECISION;
    }

    function _calculateLinearPrice(
        CurveConfig memory config,
        uint256 supply
    ) internal pure returns (uint256) {

        return config.startPrice + (config.a * supply) / PRECISION;
    }

    function _calculateExponentialPrice(
        CurveConfig memory config,
        uint256 supply
    ) internal pure returns (uint256) {

        uint256 rate = config.a;
        uint256 multiplier = PRECISION + (rate * supply) / config.maxSupply;
        return (config.startPrice * multiplier) / PRECISION;
    }

    function _calculateLogarithmicPrice(
        CurveConfig memory config,
        uint256 supply
    ) internal pure returns (uint256) {
        if (supply == 0) return config.startPrice;

        uint256 logValue = _approximateLog(supply + PRECISION);
        return config.startPrice + (config.a * logValue) / PRECISION;
    }

    function _calculateSquareRootPrice(
        CurveConfig memory config,
        uint256 supply
    ) internal pure returns (uint256) {

        uint256 sqrtValue = _sqrt(supply * PRECISION);
        return config.startPrice + (config.a * sqrtValue) / PRECISION;
    }

    function _calculateQuadraticPrice(
        CurveConfig memory config,
        uint256 supply
    ) internal pure returns (uint256) {

        uint256 term1 = (config.a * supply * supply) / (PRECISION * PRECISION);
        uint256 term2 = (config.b * supply) / PRECISION;
        return term1 + term2 + config.c;
    }

    function _calculateIntegral(
        CurveConfig memory config,
        uint256 from,
        uint256 to
    ) internal pure returns (uint256 integral) {
        if (from >= to) return 0;

        if (config.curveType == CurveType.LINEAR) {

            uint256 fromValue = (config.a * from * from) / (2 * PRECISION) + config.startPrice * from;
            uint256 toValue = (config.a * to * to) / (2 * PRECISION) + config.startPrice * to;
            integral = (toValue - fromValue) / PRECISION;
        } else {

            integral = _numericalIntegration(config, from, to);
        }
    }

    function _numericalIntegration(
        CurveConfig memory config,
        uint256 from,
        uint256 to
    ) internal pure returns (uint256 integral) {
        uint256 n = 100;
        uint256 h = (to - from) / n;

        uint256 sum = calculatePrice(config, from) + calculatePrice(config, to);

        for (uint256 i = 1; i < n; i++) {
            uint256 x = from + i * h;
            uint256 price = calculatePrice(config, x);
            sum += (i % 2 == 0) ? 2 * price : 4 * price;
        }

        integral = (sum * h) / (3 * PRECISION);
    }

    function _sqrt(uint256 x) internal pure returns (uint256) {
        if (x == 0) return 0;

        uint256 z = (x + 1) / 2;
        uint256 y = x;

        while (z < y) {
            y = z;
            z = (x / z + z) / 2;
        }

        return y;
    }

    function _approximateLog(uint256 x) internal pure returns (uint256) {
        if (x <= PRECISION) return 0;

        uint256 result = 0;

        while (x >= 2 * PRECISION) {
            x = x / 2;
            result += 693147180559945309;
        }

        if (x > PRECISION) {
            uint256 y = x - PRECISION;
            result += (y * PRECISION) / x;
        }

        return result;
    }

    function createPumpFunConfig(
        uint256 startPrice,
        uint256 targetMarketCap,
        uint256 maxSupply
    ) internal pure returns (CurveConfig memory) {

        uint256 targetPrice = (targetMarketCap * PRECISION) / maxSupply;
        uint256 a = ((targetPrice - startPrice) * PRECISION) / maxSupply;

        return CurveConfig({
            curveType: CurveType.LINEAR,
            a: a,
            b: 0,
            c: 0,
            startPrice: startPrice,
            targetPrice: targetPrice,
            maxSupply: maxSupply
        });
    }
}
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 100
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
Factory|addr:0x35540be904fe2aa34369bce2072d0c6d6ddae7e3|verified:true|block:23544002|tx:0xbc0a4ef752f8909818b998fdbaca702e4cf71702cdd3c8158ba7988829d1a525|first_check:1760082313

Submitted on: 2025-10-10 09:45:14

Comments

Log in to comment.

No comments yet.