Skip to content

Curve migration and LP vaults

Source: sui/migrators/sources. The generated migrators reference includes complete adapter signatures and venue requirements.

Anyone can migrate MigrationReady through its original adapter; only that adapter’s stored witness authorizes launch::migrate. Migration can follow the final buy in the same PTB. It pays project allocations, accrues Blast’s one-time allocation in the launch, disposes of unsold curve tokens plus pending_burn, changes state to Migrated, and hands pool balances to the adapter. Opening-round delivery balances remain intact.

Disposal burns through the Coin Registry when supply is burn-only; otherwise it sends tokens to the zero address. The adapter must create and seed the venue pool and share an LpVault in that same transaction. Any failure rolls everything back. There is no cancellation or migration timeout.

Adapter Requirements and custody
cetus::migrate<Meme, Quote, CoinA, CoinB> Both package versions, shared Meme currency, VenueConfig, Cetus config/pools, LP Burn manager, and clock. Check Cetus’s canonical coin order and exact pair. Uses the reserved creation cap to create a new pool; never adopts an existing pool. Burns its full-range migration position through Cetus LP Burn and stores the CetusLPBurnProof in the vault.
bluefin::migrate<Meme, Quote> Both package versions, Meme and Quote currencies, Bluefin config, exact current SUI pool-creation fee, and clock. Creates Pool<Meme, Quote> and holds its widest-range position in the vault. Bluefin records the transaction sender as pool manager for reward-emission administration.

The initial price derives from the pool allocation balances, rather than the last curve price. Venue rounding can leave residual coins; those become protocol residuals in the vault, claimable only by TreasuryAdmin. They are separate from Blast’s migration allocation in the launch fee ledger. No current call withdraws a vault position. The migrators package remains upgradeable; see custody risks.

Cetus’s own pool-manager role can still pre-create the reserved pair’s pool, and its configuration can remove a registered tick spacing. The current adapter will not adopt that pool or select another tier; the launch remains MigrationReady. There is no recovery entrypoint for these cases without a migrators upgrade.

Anyone can call the venue’s collect_fees, with the vault, migrators version, LpFeePolicy, mutable Meme currency, matching venue pool/config, and clock; Cetus also takes its burn manager and correct coin ordering. A wrong pool aborts. Empty collections are valid.

For each asset, Blast takes ceil(gross * policy_bps / 10_000) using the coin-specific pair if present, otherwise defaults. FeeAdmin can change each rate through 10,000 BPS without a delay; TreasuryAdmin controls the destination. These are independent of launchpad trade-fee policy. Source defaults are zero, not a live operational rate.

The remainder uses exact largest-remainder apportionment over creator, auto-LP, rewards, burn, and recipients in that order, with earlier entries winning ties. Creator/auto-LP/rewards balances accumulate; recipients are paid directly. Burn tokens are disposed of now; burn quote accumulates for buyback.

Without a partner, Blast’s part pays immediately. With one, it accumulates as unpaid_protocol_*; anyone settles it with vault::claim_protocol_lp_fees_with_partner, the recorded partner, current policy, and clock. The partner receives floor(held * current_partner_share / 10_000); the remainder pays the current policy destination. Partner identity is inherited from the launch.

vault::claim_creator_fees takes the vault, migrators version, launch, and its live CurveFeeCap<Meme>, returning both fee coins. It does not collect pending pool fees; collect first if needed. This claim is independent of launch::claim_creator_fees.

To change future routing, build a new FeeSplit and use the venue’s settle_and_update_fee_split with the live cap, launch, collection inputs, and new split. It collects under the previous split before committing the replacement. Existing vault balances retain their purpose. Reassignment of the launch’s live cap also changes authority over this vault.

Collection attempts to reinvest auto-LP when both assets are available, retaining excess for later. Cetus uses a separate full-range position because the burned migration position cannot accept liquidity. Bluefin adds to the held migration position. Current pool price determines the deposit; transaction-level price manipulation can skim part of auto-LP’s value.

Only BuybackAdmin calls the venue’s buyback_and_burn. It swaps accumulated burn_quote in the vault’s own pool, checks min_meme_out, disposes of purchased tokens, and retains unspent quote. A burn allocation does not imply a timed or permissionless buyback.

RewardsAdmin publishes through blast_holder_rewards::publish_round: next sequential round number, contiguous checkpoint interval after the first, 32-byte root and manifest digest, 1–65,536 leaves, and non-zero funded Meme/Quote budget. It moves the budget from the vault into a shared Round. The contract does not verify the off-chain accounting or that leaves sum to the budget.

Anyone can call blast_holder_rewards::claim with round, migrators version, index, beneficiary, both amounts, and sibling proof. It checks index, unpaid status, non-zero beneficiary and budget, and proof; marks the leaf paid; then pays only the beneficiary. Insufficient budget aborts atomically. Rounds do not expire and have no cancel/sweep path.

Blake2b-256 format, with integer fields encoded as u64 little-endian:

leaf = H(0x00 || ASCII("blast-holder-rewards-v1") || vault_id[32]
|| round || index || beneficiary[32] || meme_amount || quote_amount)
node = H(0x01 || left[32] || right[32])

Use the vault ID, not the reward round object’s ID. Leaves are in index order. An odd last node pairs with itself; at each level the index’s parity selects left/right, then the index halves. Proofs contain exactly one 32-byte sibling per tree level; one leaf needs an empty proof. These rules belong to launchpad rewards, not the separate presale reward implementation.