The Pump.fun Bonding Curve Explained (With the Actual Math)
How Pump.fun's constant-product bonding curve prices tokens, where the virtual reserves come from, how the ~85 SOL migration threshold works, and how to compute price and market cap yourself.
Every Pump.fun price you have ever seen comes out of one equation. Once you understand the constant-product bonding curve and its virtual reserves, you can compute price, market cap, and migration progress for any token directly — no API, no guesswork.
It’s a constant-product AMM
Pump.fun’s bonding curve is a constant-product market maker — the same x · y = k invariant Uniswap and Raydium use — but with a twist: the reserves are virtual. Instead of requiring a real liquidity provider to deposit both sides, the contract initializes the curve with virtual token and SOL reserves that define the starting price and shape of the curve.
virtual_sol_reserves × virtual_token_reserves = k (constant)
price_per_token (in SOL) = virtual_sol_reserves / virtual_token_reservesWhen someone buys, tokens leave virtual_token_reserves and SOL is added to virtual_sol_reserves. Because the product k must stay constant, removing tokens forces the SOL side — and therefore the price — up. Selling does the reverse. There is no order book; the curve is the counterparty to every trade.
Where the numbers start
The commonly used initial parameters for a fresh Pump.fun curve are approximately:
| Reserve | Initial value | Meaning |
|---|---|---|
| virtual_token_reserves | ~1,073,000,000 tokens | Starting token side of the curve |
| virtual_sol_reserves | ~30 SOL | Starting SOL side — sets the opening price |
| real_token_reserves | ~793,100,000 tokens | Tokens actually available to buyers on the curve |
| token_total_supply | 1,000,000,000 | Fixed supply (6 decimals → 1e15 base units) |
With ~30 SOL against ~1.073B tokens, the opening price is roughly 30 / 1,073,000,000 ≈ 2.8 × 10⁻⁸ SOL per token — a market cap around a few thousand dollars at typical SOL prices. Every buy nudges those reserves and re-prices the whole supply.
Computing price and market cap yourself
Given the live reserves (which you can read straight off the bonding curve account — see How to Read Pump.fun Token Data On-Chain), the math is direct. Remember the unit conversions: SOL reserves are in lamports (÷ 1e9), token reserves are in base units with 6 decimals (÷ 1e6).
const solReserves = Number(virtual_sol_reserves) / 1e9; // → SOL
const tokenReserves = Number(virtual_token_reserves) / 1e6; // → tokens
const priceInSol = solReserves / tokenReserves; // SOL per token
const priceInUsd = priceInSol * solPriceUsd;
const supply = 1_000_000_000; // fixed
const marketCap = priceInUsd * supply;The migration threshold
The curve is designed to “complete” once buyers have absorbed the real token reserves — historically when about ~85 SOL has been raised into the curve, corresponding to roughly a $69k market cap. At that point the complete flag on the account flips to true and the token graduates to a real AMM pool (Raydium historically; PumpSwap since 2025), where the accumulated SOL and remaining tokens seed genuine liquidity.
// Rough migration progress from live reserves
const raised = (Number(virtual_sol_reserves) / 1e9) - 30; // minus the initial virtual 30
const progress = Math.min(1, raised / 85); // 0.0 → 1.0
console.log(`${(progress * 100).toFixed(1)}% to migration`);complete flag rather than inferring it.Why devs should care
- Slippage grows along the curve. Early buys move price far more per SOL than late buys — the curve flattens as reserves grow.
- Market cap is a curve output, not an input. You cannot “set” it; it is entirely a function of how much SOL is in the curve.
- Migration is a liquidity event. Graduating to an AMM changes the microstructure — real LPs, real slippage, and MEV all appear post-migration.