Loading...
Loading...
PumpFun bonding curve math, graduation mechanics, instruction parsing, and PumpSwap migration
npx skill4agent add agiprolabs/claude-trading-skills pumpfun-mechanicsk = virtualSolReserves × virtualTokenReserves| Parameter | Value |
|---|---|
| Initial Virtual SOL | 30 SOL (30,000,000,000 lamports) |
| Initial Virtual Tokens | ~1.073B tokens (1,073,000,000,000,000 raw, 6 decimals) |
| Token Total Supply | 1B tokens (1,000,000,000,000,000 raw) |
| Real Token Reserves | ~793M tokens (793,000,000,000,000 raw) |
| Real SOL Reserves | 0 (no real SOL at launch) |
| Fee | 1% (applied externally by the program) |
price_sol_per_token = virtual_sol_reserves / virtual_token_reserves
# In human-readable units:
price = (virtual_sol / 1e9) / (virtual_token / 1e6)
# At genesis: 30 / 1,073,000,000 ≈ 2.796e-8 SOL/token
# At graduation: ~4.1e-7 SOL/token (~14.7x from launch)def buy_tokens(v_sol: int, v_tok: int, real_tok: int, sol_in: int) -> int:
"""Calculate tokens received for a given SOL input.
Args:
v_sol: Virtual SOL reserves (lamports).
v_tok: Virtual token reserves (raw).
real_tok: Real token reserves (raw).
sol_in: SOL to spend (lamports, BEFORE 1% fee).
Returns:
Tokens received (raw units).
"""
k = v_sol * v_tok
new_v_sol = v_sol + sol_in
new_v_tok = k // new_v_sol + 1 # +1 matches on-chain rounding
tokens_out = v_tok - new_v_tok
return min(tokens_out, real_tok)def sell_tokens(v_sol: int, v_tok: int, real_sol: int, tokens_in: int) -> int:
"""Calculate SOL received for selling tokens.
Args:
v_sol: Virtual SOL reserves (lamports).
v_tok: Virtual token reserves (raw).
real_sol: Real SOL reserves (lamports).
tokens_in: Tokens to sell (raw units).
Returns:
SOL received (lamports, BEFORE 1% fee).
"""
k = v_sol * v_tok
new_v_tok = v_tok + tokens_in
new_v_sol = k // new_v_tok
sol_out = v_sol - new_v_sol - 1 # -1 matches on-chain floor rounding
return min(sol_out, real_sol)def buy_cost(v_sol: int, v_tok: int, tokens_wanted: int) -> int:
"""Calculate SOL needed to buy exact token amount.
Returns:
SOL cost in lamports (before fee). Returns max int if impossible.
"""
if tokens_wanted >= v_tok:
return 2**64 - 1 # impossible
k = v_sol * v_tok
new_v_tok = v_tok - tokens_wanted
new_v_sol = k // new_v_tok + 1
return new_v_sol - v_sol# Buying: fee deducted from SOL input before curve
actual_sol_to_curve = sol_input * 0.99
# Selling: fee deducted from SOL output after curve
actual_sol_received = sol_from_curve * 0.99
# Roundtrip minimum cost: ~2% from fees alone, plus price impactmarket_cap_sol = (token_total_supply * virtual_sol_reserves) / virtual_token_reservesrealSolReservescompletetrueCompleteEvent5f72619cd42e9808GRADUATION_THRESHOLD = 85_000_000_000 # 85 SOL in lamports
fill_pct = (real_sol_reserves / GRADUATION_THRESHOLD) * 100.0pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8| Program/Account | Address |
|---|---|
| PumpFun Program | |
| PumpSwap Program | |
| Fee Program | |
| Global Account | |
| Fee Recipient | |
| Event Authority | |
sha256("event:<EventName>")[0..8]| Event | Discriminator (hex) |
|---|---|
| CreateEvent | |
| TradeEvent | |
| CompleteEvent | |
mint: pubkey 32 bytes
solAmount: u64 8 bytes
tokenAmount: u64 8 bytes
isBuy: bool 1 byte
user: pubkey 32 bytes
timestamp: i64 8 bytes
virtualSolReserves: u64 8 bytes
virtualTokenReserves: u64 8 bytes
realSolReserves: u64 8 bytes
realTokenReserves: u64 8 bytesOffset 0: discriminator 8 bytes
Offset 8: virtualTokenReserves u64
Offset 16: virtualSolReserves u64
Offset 24: realTokenReserves u64
Offset 32: realSolReserves u64
Offset 40: tokenTotalSupply u64
Offset 48: complete bool (1 byte)
Offset 49: creator pubkey (32 bytes)| PDA | Seeds |
|---|---|
| Bonding Curve | |
| Bonding Curve V2 | |
| Creator Vault | |
| Instruction | Hex | Notes |
|---|---|---|
| buy_exact_sol_in (V2) | | Current production buy |
| sell (V2) | | Current production sell |
| buy (V1/legacy) | | Legacy, still seen occasionally |
| create | | Token creation |
[0..8]: discriminator
[8..16]: spendable_sol_in u64 LE (total SOL budget, fees deducted internally)
[16..24]: min_tokens_out u64 LE (slippage floor)[0..8]: discriminator
[8..16]: amount_tokens u64 LE (tokens to sell, raw)
[16..24]: min_sol_output u64 LE (minimum SOL out, lamports)def price_impact(v_sol: int, v_tok: int, sol_in: int) -> float:
"""Calculate price impact for a buy as a percentage."""
spot = v_sol / v_tok
tokens = buy_tokens(v_sol, v_tok, v_tok, sol_in)
if tokens == 0:
return float('inf')
exec_price = sol_in / tokens
return (exec_price / spot - 1) * 100
# Example: 1 SOL buy at genesis
# impact = price_impact(30_000_000_000, 1_073_000_000_000_000, 1_000_000_000)
# ≈ 3.3% price impactreferences/bonding_curve_math.mdreferences/graduation_process.mdreferences/instruction_reference.mdscripts/curve_calculator.pyscripts/parse_events.py