Protocol
Bonding curve
Virtual reserves, buy and sell quotes, progress, and graduation.
Constant product on virtual reserves#
Each launch gets its own curve pool. It prices trades with the same invariant a Uniswap V2 pair uses, with one twist: both reserves start out virtual. The pool quotes against numbers, not against deposits.
virtualEthReserve × virtualTokenReserve = kBuying pushes ETH into the virtual reserve and pulls tokens out, so the price rises. Selling does the reverse. Because
k is fixed at deployment, the entire price path of a launch is known before anybody trades.
That is the whole reason a launch can trade with nobody having seeded it. A real constant-product pool needs both sides deposited before it can quote anything. A virtual one opens at a defined price and lets real ETH accumulate as people buy.
The two sets of reserves#
| Reserve | What it does |
|---|---|
| Virtual ETH and token | price the next trade |
| Real ETH | what the pool actually holds, and what sells are paid from |
| Real token | curve tokens left to sell |
| DEX token | the 200M held back for the pool at graduation |
| Accrued fees | earned but unclaimed, sitting inside the real ETH balance |
Sells are paid from real ETH minus the accrued fees. That subtraction is why one person's sell can never spend fees somebody else has already earned.
Starting values#
| Virtual ETH reserve | 1.2 ETH |
| Virtual token reserve | 1,066,666,666.666666666666666666 |
| Opening price | ~0.000000001125 ETH per token |
Quoting a buy#
The fee comes off the top, then the remainder moves the curve:
fee = grossEthIn × 200 / 10000 // 2%
netEthIn = grossEthIn - fee
nextVirtualEthReserve = virtualEthReserve + netEthIn
nextVirtualTokenReserve = k / nextVirtualEthReserve
tokenOut = virtualTokenReserve - nextVirtualTokenReserveThe quote function hands back all of it: ETH used, ETH refunded, the fee, tokens out, both next reserves, and a flag saying whether this buy would finish the curve. So an interface can show the exact outcome before you sign instead of estimating one.
When your buy is the last one#
If your buy would take more tokens than the curve has left, it neither reverts nor fills you at a broken price. The pool works out the smallest amount of ETH that still buys every remaining token, spends exactly that, refunds the rest in the same transaction, and graduates the launch.
enough tokens left ──▶ normal fill, no refund
not enough left ──▶ spend only what is needed, refund the rest, graduateYou cannot overpay into a graduation. Send 10 ETH at a curve that needs 0.4 ETH to finish and about 9.6 ETH comes straight back in the same transaction.
Quoting a sell#
nextVirtualTokenReserve = virtualTokenReserve + tokenIn
nextVirtualEthReserve = k / nextVirtualTokenReserve
grossEthOut = virtualEthReserve - nextVirtualEthReserve
fee = grossEthOut × 200 / 10000 // 2%
netEthOut = grossEthOut - feeTwo limits apply: you cannot sell more than the curve has actually circulated, and a payout is capped at the ETH that is spendable after set-aside fees. Both are there so the pool can always cover what it owes.
Fees are charged in ETH on both sides, never in tokens, so selling burns no supply.
Progress#
Progress is just the share of the 800M curve allocation that has sold, reported as a fixed-point number where 1e18
means 100%. The progress bar you see on a token page is that value, nothing more clever.
Graduation, derived#
Graduation fires the moment the curve allocation is gone. Selling all 800M tokens moves the virtual reserves to a known end state, and that single fact fixes every headline number:
virtual token reserve at the end = 1,066,666,666.666… - 800,000,000
= 266,666,666.666…
virtual eth reserve at the end = k / 266,666,666.666… = 4.8 ETH
net ETH collected = 4.8 - 1.2 = 3.6 ETH
final price = 4.8 / 266,666,666.666… = 0.000000018 ETH per token
graduation FDV = 0.000000018 × 1,000,000,000 = 18 ETHThe 2% buy fee comes off the top, so the ETH people actually spend getting there is 3.6 / 0.98 ≈ 3.673469 ETH, of
which about 0.073469 ETH is fee. That splits 70/30 between creator and protocol. Neither share goes into the pool —
only the clean 3.6 ETH migrates.
| Amount | |
|---|---|
| Gross ETH in, no sells | ~3.67346938775510204 ETH |
| Total curve fee | ~0.07346938775510204 ETH |
| Creator share (70%) | ~0.051428571428571428 ETH |
| Protocol share (30%) | ~0.022040816326530612 ETH |
| Migrated to the pool | 3.6 ETH |
Those figures assume nobody sells. Sells pay fees too, so a curve with churn collects more in fees overall while still migrating exactly 3.6 ETH.
Why the trigger is a token count, not an ETH target#
Graduation could just as easily fire at an ETH threshold. Counting tokens makes the ending exact: the final reserves, the final price, and the pool's opening price are all known before anyone trades, which is what lets the migration check that the two prices agree inside one transaction. An ETH target would leave the token side floating and put a price gap back into the handoff.
Next: graduation covers how that 3.6 ETH and 200M tokens become a locked pool.