Skip to content

Developer overview

blast_presale is a standalone Sui Move package for presales. It mints a new coin’s full supply, takes commitments in a quote coin, settles, and migrates the liquidity into a full-range Cetus or Bluefin pool. A sale overflows by default, filling every wallet at one rate, or holds commitments to its raise, first come, first served, under a hard cap. It shares the Blast ACL and partner registry with Blast’s bonding-curve launchpad, but no sale state or launch logic.

The participant and team pages call migration launch.

Every step is a public Move call, and most are permissionless: anyone can settle, migrate, claim for a participant, collect fees, or cancel a stalled sale. This guide shows how to build those calls from your own app, keeper, or indexer.

  • Source: sui/presale in blast-v2-contracts. Source and tests are authoritative; this site explains them.
  • Integrator reference generated from source: llms/presale.txt. It lists every public function, type, event, and abort code, and is written to be handed to an AI agent.
  • Design records: ADR 0099 and its amendments in the decision index.
Module Role
blast_presale The Presale object: creation, commitments, settlement, claims, cancellation.
cetus, bluefin Venue adapters: create a sale for that venue, migrate it, collect its fees.
presale_vault The Vault that holds a migrated sale’s LP position, or a team’s own locked position, and splits its fees.
holder_rewards Merkle reward rounds funded from a vault’s holder share.
fee_policy Blast’s fee rates and payout destination.
creation_policy Allowlists checked at creation: quote types, migrators, partners.
blast_presale_domain Presale roles used with the shared Blast ACL.
package_admin Holds the dependency-only UpgradeCap.
venue_config The shared VenueConfig: Cetus pool-creation caps and each sale’s pool tier.
bps, merkle_tree, migration_math Helpers.
Object Ownership Purpose
Presale<SaleToken, Quote> Shared, one per sale Holds commitments, the minted supply, and the terms until migration or refund. key only, so it must be shared in the transaction that creates it.
PresaleCap Owned by the creator Claims migration residuals; can be destroyed after a cancellation. Cannot change terms or move funds.
Vault<Meme, Quote> Shared, one per migrated sale or locked position Holds the Bluefin position or the Cetus LP-burn proof, residuals, and the holder-reward share.
Round<Meme, Quote> Shared, one per reward round A published holder-reward Merkle root and its budget.
Vesting<T> Shared, one per vested payout An irrevocable linear schedule from the external blast_fun_vesting package.
FeePolicy, CreationPolicy, VenueConfig, PackageAdmin Shared singletons Created once at deployment. Administration uses the existing shared Blast ACL.

The venue modules and the vault call the sale coin Meme. It is the same type as SaleToken.

Creation runs in one transaction: a venue’s new returns a PresaleInitializer, setters record the terms, and finalize returns the Pending sale and its PresaleCap. See Create a sale.

Pending → Open → Funded → Migrated
Open → Cancelled (settle, total below the raise)
Funded → Cancelled (cancel_unlaunched, from the LP deadline)
State Allows
Pending Exists only inside the creation transaction, between finalize and share: Blast’s set_protocol_fees, then share.
Open Before start_ms: Blast’s set_protocol_fees. Commits from start_ms until end_ms. settle from end_ms, or earlier once the raise is full under a hard cap that closes the sale when filled.
Funded Migration at any time. cancel_unlaunched from end_ms + liquidity_window_ms, where end_ms is the close after an early close.
Migrated claim for tokens plus overflow refund.
Cancelled claim for a full refund. destroy_cap.

Once the liquidity deadline passes, migration and cancellation race, and whichever lands first wins.

Blast operators use a blast_acl::AdminCap granted the required presale role. In the same transaction, blast_acl::sign_in<Role>(acl, admin_cap) returns an AdminWitness<Role>; pass it by reference to the admin call. Roles come from blast_presale_domain, and a role from another package does not authorize presale calls.

Role Can
FeeAdmin Set new-sale rates, change a sale’s rates before start_ms, change vault LP-fee rates, and accept or remove partners for new sales.
TreasuryAdmin Change the fee destination.
ListingAdmin Allow or disallow quote types for new sales and vaults.
AdapterAdmin Allow or disallow migrator witnesses for new sales and vaults.
RewardsAdmin Publish holder-reward rounds and settle their optional gas reserves.
UpgradeAdmin Authorize and commit dependency-only upgrades.

The creator’s PresaleCap separately claims migration residuals and can be destroyed after a cancellation. It grants no admin role.

Nobody can pause a sale, move commitments, or change its windows, recipients, eligibility, or fee split. The package’s UpgradeCap is sealed for dependency-only upgrades, so presale logic never changes.

blast_presale::new, finalize, and migrate are public, so a module in another package can be a migrator with its own sealed witness once Blast’s CreationPolicy allows it, for example a partner’s vendor package under sui/vendors. Its sales follow every sale rule here, but a vendor sale has no Blast vault: no Blast LP fees, no holder-reward rounds, and no residual claims. The newer built-in Aftermath adapter in source creates a vault; see Aftermath (source preview).

The Aftermath DAO-pool vendor follows the same initializer flow: its own new returns the PresaleInitializer, the blast_presale setters configure it, and its own finalize sets a treasury-only fee split, finalizes the sale, binds the Aftermath pool creation, sends the PresaleCap to the partner treasury, and returns the sale for share. Both calls need the vendor’s own AdminCap. The route is documented in llms/presale.txt.

  • Rates are basis points out of 10,000, built with bps::new(value).
  • Times are Unix milliseconds read from the shared Clock at 0x6.
  • Amounts are atomic units of each coin.
  • Rounding uses largest-remainder apportionment: every atomic unit of supply, raise, and fees lands in exactly one share.
  • Errors are Move clever errors that name the module and constant. See Errors.

First-party contract code is under the Business Source License 1.1. Read it before reusing the source.