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": []
}
}}
Submitted on: 2025-10-10 09:45:14
Comments
Log in to comment.
No comments yet.