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.

Ir para a instalação

Informações da origem

Repositório
ccashwell/evm-cortex
Última atividade na origem
10 de abril de 2026 às 16:31
Idioma detectado do SKILL.md
inglês
Estrelas
131
Forks
18

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
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
Ver no GitHub