Skip to main content

token-bonding-curves

Use when implementing bonding curve token sales, automated market makers with supply-dependent pricing, or continuous token models. Covers linear, polynomial, logarithmic, and Bancor-style curves.

설치로 이동

소스 정보

저장소
ccashwell/evm-cortex
최근 소스 활동
2026년 4월 10일 16:31
감지된 SKILL.md 언어
영어
스타
131
포크
18

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
token-bonding-curves
description
Use when implementing bonding curve token sales, automated market makers with supply-dependent pricing, or continuous token models. Covers linear, polynomial, logarithmic, and Bancor-style curves.
# Token Bonding Curves ## Concept A bonding curve is a mathematical function that defines the price of a token as a function of its supply. As supply increases, price increases along the curve. Tokens are minted on buy and burned on sell, with a reserve backing the curve. ``` price = f(supply) cost_to_buy(n) = integral(f, supply, supply + n) proceeds_from_sell(n) = integral(f, supply - n, supply) ``` ## Curve Types | Curve | Formula | Behavior | |-------|---------|----------| | Linear | `price = m * supply + b` | Steady price increase | | Polynomial | `price = a * supply^n` | Accelerating increase (n>1) | | Logarithmic | `price = a * ln(supply) + b` | Decelerating increase | | Sigmoid | `price = a / (1 + e^(-k*(supply-mid)))` | S-curve with plateau | | Bancor | `price = reserve / (supply * CW)` | Connector weight model | ## Linear Bonding Curve Implementation ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; contract LinearBondingCurve is ERC20, ReentrancyGuard { uint256 public immutable slope; // price increase per token (in wei per token) uint256 public immutable basePrice; // starting price (in wei per token) uint256 public reserveBalance; constructor(uint256 _slope, uint256 _basePrice) ERC20("BondingToken", "BOND") { slope = _slope; basePrice = _basePrice; } /// @notice Price at a given supply level function priceAtSupply(uint256 supply) public view returns (uint256) { return basePrice + (slope * supply / 1e18); } /// @notice Cost to buy `amount` tokens at current supply /// @dev Integral of linear function: base*amount + slope*(s1^2 - s0^2) / (2 * 1e18) function getBuyCost(uint256 amount) public view returns (uint256) { uint256 s0 = totalSupply(); uint256 s1 = s0 + amount; uint256 baseCost = basePrice * amount / 1e18; uint256 slopeCost = slope * (s1 * s1 - s0 * s0) / (2 * 1e36); return baseCost + slopeCost; } /// @notice Proceeds from selling `amount` tokens at current supply function getSellProceeds(uint256 amount) public view returns (uint256) { uint256 s0 = totalSupply(); require(amount <= s0, "exceeds supply"); uint256 s1 = s0 - amount; uint256 baseCost = basePrice * amount / 1e18; uint256 slopeCost = slope * (s0 * s0 - s1 * s1) / (2 * 1e36); return baseCost + slopeCost; } function buy(uint256 minTokens) external payable nonReentrant { uint256 cost = getBuyCost(minTokens); require(msg.value >= cost, "insufficient payment"); reserveBalance += cost; _mint(msg.sender, minTokens); uint256 refund = msg.value - cost; if (refund > 0) { (bool ok, ) = msg.sender.call{value: refund}(""); require(ok, "refund failed"); } emit Buy(msg.sender, minTokens, cost); } function sell(uint256 amount) external nonReentrant { require(balanceOf(msg.sender) >= amount, "insufficient balance"); uint256 proceeds = getSellProceeds(amount); require(proceeds <= reserveBalance, "insufficient reserve"); reserveBalance -= proceeds; _burn(msg.sender, amount); (bool ok, ) = msg.sender.call{value: proceeds}(""); require(ok, "transfer failed"); emit Sell(msg.sender, amount, proceeds); } event Buy(address indexed buyer, uint256 amount, uint256 cost); event Sell(address indexed seller, uint256 amount, uint256 proceeds); receive() external payable {} } ``` ## Bancor Formula The Bancor formula uses a Connector Weight (CW) to relate reserve balance, supply, and price: ``` price = reserveBalance / (supply * CW) returnAmount = supply * ((1 + depositAmount / reserveBalance)^CW - 1) ``` ```solidity /// @notice Bancor buy calculation using exponentiation by Taylor series /// @param supply Current token supply /// @param reserveBalance Current reserve balance /// @param reserveRatio Reserve ratio (CW) in PPM (1-1000000) /// @param depositAmount ETH/token deposited function calculatePurchaseReturn( uint256 supply, uint256 reserveBalance, uint32 reserveRatio, uint256 depositAmount ) public pure returns (uint256) { if (reserveRatio == 1000000) { // Special case: CW = 100% -> linear return supply * depositAmount / reserveBalance; } // For fractional CW, use Power function (fixed-point math library) // return supply * (power(1 + depositAmount/reserveBalance, CW) - 1) } ``` ## Polynomial Curve ```solidity // price = coefficient * supply^exponent // cost = integral = coefficient * (s1^(exp+1) - s0^(exp+1)) / (exp+1) function getPolynomialCost(uint256 amount) public view returns (uint256) { uint256 s0 = totalSupply(); uint256 s1 = s0 + amount; uint256 exp1 = exponent + 1; return coefficient * (power(s1, exp1) - power(s0, exp1)) / exp1; } ``` ## Buy/Sell Spread Add a spread to capture value for the protocol: ```solidity uint256 public constant SELL_FEE_BPS = 300; // 3% sell fee function sell(uint256 amount) external { uint256 grossProceeds = getSellProceeds(amount); uint256 fee = grossProceeds * SELL_FEE_BPS / 10000; uint256 netProceeds = grossProceeds - fee; // fee stays in reserve, increasing price floor for remaining holders } ``` ## Checklist - [ ] Reserve balance always covers the integral under the curve for all outstanding tokens - [ ] Buy/sell functions use `nonReentrant` (ETH transfers create reentrancy risk) - [ ] Price function is monotonically increasing with supply - [ ] Integer math doesn't lose significant precision in curve calculations - [ ] Consider overflow in `supply^n` calculations for polynomial curves - [ ] Sell proceeds never exceed reserve balance - [ ] Front-running mitigation: slippage tolerance or commit-reveal - [ ] Test buy/sell round-trip: buy then immediately sell should have minimal loss (only spread) - [ ] Test extreme values: very large buys, selling entire supply
GitHub에서 보기