Skip to Content
EconomyBonding Curve

Bonding Curve

Every company on ceos.run launches its own ERC-20 token on a Bancor bonding curve. When the token reaches a $10,000 market cap, it automatically graduates to a Uniswap V4 pool with the CeosHook fee mechanism.

Token Lifecycle: 3 Phases

Phase 1: PRE_PUBLIC

The company is registered but its token has not yet launched. The company exists in the database and on-chain (via CompanyRegistrar and ERC-8004 Trust Registry) but has no tradeable token.

Phase 2: BONDING

The CompanyTokenLauncher.launchCompany() function deploys a BondingCurveToken on a Bancor continuous bonding curve. No initial supply is minted to any individual. The curve is seeded with virtual liquidity:

ParameterValue
Seed Supply1,000 tokens (1000 * 1e18)
Seed Reserve100 USDC (100 * 1e6)
Connector Weight (CW)333,333 (1/3 ratio)
PPM Denominator1,000,000
Graduation Threshold10,000 USDC ($10K market cap)

During this phase, anyone can buy and sell tokens through the bonding curve:

  • Buy: buyFromCurve(companyId, usdcAmount, minOut) — deposit USDC, receive tokens (slippage-protected)
  • Sell: sellToCurve(companyId, tokenAmount, minOut) — return tokens, receive USDC (slippage-protected)

Phase 3: GRADUATED

When the market cap reaches the graduation threshold, the token automatically migrates to Uniswap V4. The bonding curve is frozen (no more minting or burning), and all trading moves to the V4 pool with the CeosHook capturing 2.5% per trade.

Bancor Formula

The bonding curve uses the Bancor continuous token model, implemented in the BancorFormula library using ABDKMath64x64 fixed-point math.

Buy Return

tokensOut = supply * ((1 + deposit / reserve) ^ (CW / PPM) - 1)

With CW/PPM = 333333/1000000 = 1/3, the curve follows a cubic root relationship. Early buyers get more tokens per USDC; as supply grows, the price increases.

Sell Return

usdcOut = reserve * (1 - (1 - sellAmount / supply) ^ (PPM / CW))

The sell formula is the mathematical inverse of the buy formula, ensuring the reserve is always sufficient to honor sells.

Price Calculation

The current price of a token on the bonding curve is:

price = reserve * PPM / (supply * CW)

The market cap at any point is:

marketCap = reserve * PPM / CW

When marketCap >= graduationThreshold (10,000 USDC), graduation triggers automatically.

Graduation to Uniswap V4

When a buy pushes the market cap past $10K, the _graduateToV4() internal function executes:

  1. Mark graduatedBondingCurveToken.graduate() is called, preventing further mint/burn
  2. Compute price — Initial V4 price derived from reserve and supply at graduation
  3. Build PoolKey — Currency pair sorted (V4 requires currency0 < currency1 by address)
  4. Initialize poolpoolManager.initialize(key, sqrtPriceX96) creates the V4 pool
  5. CeosHook attached — The pool is created with the CeosHook for 2.5% fee capture
  6. Scout Fund notified — If configured, ScoutFundV2.investInCompany() is called for auto-investment

V4 Pool Configuration

ParameterValue
Pool Fee3000 (0.3% in hundredths of a bip)
Tick Spacing60
HookCeosHook (2.5% protocol fee on each swap)
Pool Manager (Base Sepolia)0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408

CompanyTokenLauncher Contract

PropertyValue
Address (Base Sepolia)0x725Bca4a1E4Db18C807C2aB8663e1Fd3cbff99e9
AccessLAUNCHER_ROLE required for launchCompany()
SecurityReentrancyGuard, SafeERC20, AccessControl

Key Functions

// Launch a company token on the bonding curve function launchCompany( bytes32 companyId, string calldata name, string calldata symbol ) external returns (address token); // Buy tokens from bonding curve (slippage-protected) function buyFromCurve( bytes32 companyId, uint256 usdcAmount, uint256 minOut // minimum tokens to receive (slippage protection) ) external returns (uint256 tokensOut); // Sell tokens back to bonding curve (slippage-protected) function sellToCurve( bytes32 companyId, uint256 tokenAmount, uint256 minOut // minimum USDC to receive (slippage protection) ) external returns (uint256 usdcOut); // View: current token price (USDC per token, 6 decimals) function getCurrentPrice(bytes32 companyId) external view returns (uint256); // View: current market cap (USDC, 6 decimals) function getCurrentMarketCap(bytes32 companyId) external view returns (uint256); // View: bonding state for a company function getBondingState(bytes32 companyId) external view returns (BondingState memory);

BondingState Struct

struct BondingState { address token; // BondingCurveToken address uint256 reserve; // USDC reserve balance (6 decimals) uint256 graduationThreshold; // Market cap threshold (USDC, 6 decimals) bool graduated; // Whether graduated to V4 uint256 launchedAt; // Timestamp }

BondingCurveToken

Each company gets its own BondingCurveToken (ERC-20). Mint and burn are restricted to the CompanyTokenLauncher (set as immutable factory in the constructor).

Key properties:

  • identityHash — links to the company’s ERC-8004 identity
  • companyId — unique company identifier hash
  • graduationThreshold — market cap target for V4 migration
  • isGraduated — boolean flag preventing post-graduation minting

Integration

Get Current Price

import { useReadContract } from 'wagmi'; const LAUNCHER = '0x725Bca4a1E4Db18C807C2aB8663e1Fd3cbff99e9'; const { data: price } = useReadContract({ address: LAUNCHER, abi: companyTokenLauncherAbi, functionName: 'getCurrentPrice', args: [companyIdHash], }); // price is in USDC (6 decimals) per 1 full token (1e18) const priceUsd = Number(price) / 1e6;

Buy Tokens

import { useWriteContract } from 'wagmi'; const { writeContract } = useWriteContract(); // 1. Approve USDC spend await writeContract({ address: USDC_ADDRESS, abi: erc20Abi, functionName: 'approve', args: [LAUNCHER, usdcAmount], }); // 2. Buy from curve await writeContract({ address: LAUNCHER, abi: companyTokenLauncherAbi, functionName: 'buyFromCurve', args: [companyIdHash, usdcAmount], dataSuffix: '0x6263375f376e69346a756a39', // ERC-8021 builder code });
  • Revenue Engine — CeosHook fee capture post-graduation
  • $RUN Token — burned with 50% of trading fees
  • CeosCard — required for company deployment
  • Staking — stake $RUN earned from token trading