Completion and graduation
A launch ends its life on the curve in two steps. Completion happens inside a buy, the moment the price reaches the migration price. Graduation is a separate, permissionless instruction that moves the raised quote and the reserved base into a new Pina AMM pool, where the token trades from then on.
Trading ──Buy reaches the migration price──▶ Completed ──Graduate (anyone)──▶ Graduated ▲ │ │ │ └──┘ Buy / Sell no trading trades on the Pina AMMCompletion
CreateConfig derives migration_sqrt_price, the price at which the curve has raised migration_quote_threshold. Every buy stops at that price:
- the buyer receives the base the curve sells up to the migration price;
- the buyer pays only the quote the curve used plus its fee; the rest of
quote_amount_instays in their account; - the launch’s status becomes
Completedand the program emitsCompleted.
Completion therefore happens exactly at the migration price, never past it, and the last buyer is never overcharged. After completion, Buy and Sell fail with NotTrading, so the price stays where graduation will open the pool.
Graduation
Graduate can be sent by anyone once a launch is Completed. The sender pays rent for the new pool, its vaults, its LP mint, and any LP token accounts it creates (about 0.01 SOL, plus about 0.002 SOL per LP recipient). It runs in this order:
- Plan. Take the migration fee from
quote_reserve. Compute the base available for the pool: the base vault’s balance minus the creator allocation that has not been claimed yet. - Seed at the curve price. Pair the remaining quote with exactly the base it is worth at the final curve price. Whichever side is in excess is the surplus.
- Commit. Mark the launch
Graduated, record the pool, zeroquote_reserve, and add the migration fee (plus any quote surplus) to the creator and partner fee balances. This happens before any cross-program call. - Create the pool. Call the Pina AMM’s
CreatePool, signed by the launch (the depositor and LP owner) and by the program’s AMM authority PDA (the tier’s pool creator). The pool’s creator is the launch creator or the partner, perpool_creator_mode, and its creator fee is paid in the quote token. - Distribute LP. Send
creator_lp_shareof the minted LP to the creator andpartner_lp_shareto the partner, creating their associated LP token accounts when needed. Burn the rest. - Burn surplus base. Burn the base the pool did not need, shrinking the token’s supply.
- Emit
Graduatedwith the amounts.
If any step fails, the whole transaction fails and the launch stays Completed.
Price continuity
The pool opens at the curve’s final price:
pool_base = floor(pool_quote * 2^128 / sqrt_price^2)pool price = pool_quote / pool_base ≈ (sqrt_price / 2^64)^2Someone who bought the last token on the curve sees the same price on the AMM a block later. The end-to-end test completion_stops_trading_and_graduation_seeds_the_amm_at_the_curve_price checks the pool price against the curve price to within one part per million.
Where every token goes
Using the reference configuration from Designing curves (1 billion tokens, 85 SOL threshold, 50 million creator allocation, 2% migration fee):
| Tokens | Amount |
|---|---|
| Sold on the curve | ~720.6 million |
| Seeded into the AMM pool | ~167.6 million |
| Creator allocation (still vesting) | 50 million |
| Burned at graduation | ~61.7 million |
| Quote | Amount |
|---|---|
Raised on the curve (quote_reserve) |
85 SOL |
| Migration fee (creator and partner) | 1.7 SOL |
| Seeded into the AMM pool | 83.3 SOL |
Nothing stays behind except the creator’s unvested allocation and unclaimed fees, both of which remain claimable after graduation.
LP and locked liquidity
The Pina AMM mints LP to the launch, which keeps none of it. With creator_lp_share and partner_lp_share both zero, every LP token is burned and the pool’s liquidity is locked forever. The AMM tracks its own lp_supply, so burned LP is never redistributed to other liquidity providers: the locked share stays locked even as others deposit and withdraw.
The restricted AMM tier
Graduation creates the pool at its canonical address, [b"pool", amm_config, mint_0, mint_1] in the AMM. If someone could create that pool first, at a bad price, graduation would fail or start from the wrong price. The configuration’s AMM tier must therefore be restricted to this program’s AMM authority PDA, [b"amm_authority"] under the curve program. CreateConfig checks that the tier is owned by the Pina AMM and that its pool_creator_authority is that PDA, and rejects any other tier with InvalidAmmConfig. No one but the curve can create pools in it.
Sending Graduate
The CLI derives every account:
pina-curve graduate --base-mint <MINT>Clients that build the instruction themselves need the AMM accounts. With mint_0 and mint_1 the two mints sorted bytewise:
| Account | Address |
|---|---|
amm_authority |
[b"amm_authority"] under the curve program |
amm_program |
The Pina AMM, pAMMvXaqR2VVFqznf6dgvUFQjLXXAEeL9cb48cXsGeV |
amm_config |
The configuration’s amm_config |
pool |
[b"pool", amm_config, mint_0, mint_1] under the AMM |
lp_mint |
[b"pool_lp_mint", pool] under the AMM |
pool_vault0/1 |
[b"pool_vault", pool, mint_0] and [..., mint_1] under the AMM |
launch_lp_token |
The launch’s associated token account for lp_mint (SPL Token) |
Append creator and creator_lp_token when creator_lp_share is above zero, and partner and partner_lp_token when partner_lp_share is above zero; otherwise leave them out (the generated clients fill their slots with the program id). A missing required pair fails with MissingLpAccount. The full account list is in Instruction reference.
After graduation
Trade the token through the Pina AMM: pina-amm, @pina-rs/amm, pina_amm, or pina_amm_client. The launch account keeps the pool’s address in pool.