Skip to main content

Auction Lifecycle

Every token launch on Runner Protocol follows a structured lifecycle managed by the Launchpad program's state machine. This page describes each phase, the on-chain instructions that trigger transitions, and the terminal states.

State Machine

The Launchpad tracks each launch's progress through a SettlementState enum with 11 variants:

AuctionActive

There is no explicit AuctionActive state transition. Once start_slot is reached, the auction implicitly becomes active within the AuctionReady state. The CCA V2 engine enforces start_slot <= current_slot for bid placement.

Phase 1: Creation (3 Transactions)

Launch creation is split across three transactions to stay within Solana's compute and account limits:

Step 1: create_launch_step_1

Creates the LaunchConfig account and a Token-2022 mint with MetadataPointer extension.

  • Who can call: Any signer (becomes the creator/authority)
  • Validates: Protocol not paused, token allocations sum to 100%, quote mint is whitelisted, all parameters within protocol bounds
  • Creates: LaunchConfig PDA, Token-2022 mint with on-chain metadata (name, symbol, URI)
  • State after: Created

The creator defines all auction parameters at this step: total supply, auction/LP/team BPS splits, floor price, max bid price, tick spacing, auction duration, supply schedule steps, and graduation threshold. A SHA-256 hash of the supply steps is stored for integrity verification in step 3.

Step 2: create_launch_step_2

Creates five escrow accounts and distributes the minted token supply.

  • Who can call: Creator only
  • Creates: Auction escrow, LP escrow, team escrow (Token-2022), proceeds escrow (SPL Token), fee escrow (System account with 0.15 SOL for Raydium pool fee)
  • Mints and distributes: auction_bps, lp_bps, team_bps portions to respective escrows
  • State after: EscrowsInitialized

Step 3: initialize_cca_auction

Calls into CCA V2 via five sequential CPI calls to set up the auction engine.

  • Who can call: Creator only
  • CPI calls: initialize_auction, initialize_vaults, initialize_quote_vault, initialize_floor_tick, receive_tokens
  • Validates: Supply steps hash matches step 1, duration matches, start slot is reasonable
  • Transfers: Auction tokens from auction escrow into CCA V2 base vault
  • State after: AuctionReady

Phase 2: Active Auction

Once the current Solana slot reaches start_slot, the auction becomes active. During this phase:

Bidding

Bidders call place_bid on the CCA V2 program directly, depositing quote currency and specifying their max_price. Each bid:

  1. Transfers quote tokens from bidder to the CCA quote vault
  2. Computes effective demand: amount_q96 = raw_amount * Q96 * MPS / mps_remaining
  3. Creates or updates a Tick at the bid's price level
  4. Creates a Bid PDA tracking the bidder's position

Bids are placed through the CCA V2 program, not the Launchpad.

Checkpoints

At each auction block interval, checkpoints must be created to advance the auction's clearing state. Checkpoint creation is permissionless -- anyone can call create_checkpoint, and the payer covers the account rent.

Checkpoints discover the clearing price by walking the tick linked list (see Price Discovery), update the settlement accumulators, and advance the auction's cumulative MPS counter.

tip

In production, automated keeper bots handle checkpoint creation. There is an economic incentive to keep checkpoints current because it advances the auction state for all participants.

Bid Withdrawal Rules

  • In-range bids (max_price >= clearing_price): Cannot be withdrawn. This prevents strategic manipulation.
  • Out-of-range bids (max_price < clearing_price): May be withdrawn by the bidder.

Phase 3: Graduation Check

An auction graduates when the total currency raised meets or exceeds the configured graduation threshold. Graduation is a computed property checked at finalization time:

is_graduated = currency_raised_q96_x7 >= required_currency_raised

The required_currency_raised threshold is set immutably at auction creation. The auction does not stop early when the threshold is met -- it continues running until end_slot to allow continued price discovery.

Phase 4: Settlement Pipeline

After the auction ends and has graduated, settlement proceeds through four sequential, permissionless steps. Each is a separate transaction that anyone can trigger.

1. finalize_auction

Reads the CCA V2 auction's final state and records it into the LaunchConfig.

  • Who can call: Anyone (permissionless)
  • Requires: current_slot >= end_slot, auction graduated, settlement not paused
  • Records: final_clearing_price, total_tokens_cleared, finalized_at, finalized_slot
  • State after: Finalized

2. sweep_to_escrow

Transfers raised currency from CCA V2 vault to Launchpad proceeds escrow via CPI.

  • Who can call: Anyone (permissionless)
  • CPI: CCA V2 sweep_currency (transfers all quote from CCA vault to proceeds escrow)
  • Records: total_proceeds from actual escrow balance (authoritative source)
  • State after: ProceedsSwept

3. create_raydium_pool

Creates a Raydium CPMM liquidity pool and distributes proceeds.

  • Who can call: Anyone (permissionless)
  • Proceeds distribution:
total_proceeds
├── protocol_fee = proceeds * protocol_fee_bps / 10000 → treasury
└── remaining = proceeds - protocol_fee
├── lp_proceeds = remaining * lp_proceeds_bps / 10000 → Raydium pool
└── creator_proceeds = remaining - lp_proceeds → creator
  • Pool creation: Raydium CPMM initialize via raw invoke_signed (typed CPI would overflow SBF stack)
  • LP token burn: All LP tokens received from pool creation are immediately burned
  • State after: PoolCreated
LP Tokens Are Burned

LP tokens are burned programmatically during pool creation. This makes the liquidity permanent and irremovable. There is no code path or admin function to retain LP tokens.

4. enable_claims

Enables bidder token claims and renounces mint authority.

  • Who can call: Anyone (permissionless)
  • Actions:
    1. Transfers team tokens from team escrow to creator's token account
    2. CPI to CCA V2 set_claim_slot (sets to current slot, enabling claims)
    3. Renounces Token-2022 mint authority (set_authority to None)
  • State after: Settled (terminal success)
Claims Gated Behind Pool Creation

Token claims are intentionally disabled until the liquidity pool is created. This prevents an attack where bidders could claim tokens early and create a competing pool at a manipulated price, undermining the auction-discovered fair price.

Terminal States

StateMeaningHow Reached
SettledSuccess. Pool created, claims enabled, mint authority renounced.enable_claims after full settlement pipeline
CancelledCreator cancelled before auction started. All tokens returned.cancel_launch from Created or EscrowsInitialized
FailedRecoveryAuction did not graduate. Tokens recovered, bidders get full refunds.recover_failed_auction after auction ends without graduating
EmergencyWithdrawnSettlement stalled past timeout. Emergency escape hatch triggered.emergency_withdraw after finalized_slot + emergency_timeout_slots

Cancellation

The creator can cancel a launch at any point before the auction's start_slot:

  • Returns all tokens from escrows to creator
  • Returns fee escrow lamports
  • Closes all escrow accounts (rent recovery)
  • Only the creator can cancel; checked via authority == creator.key()

Failed Auction Recovery

If an auction ends without graduating:

  • CPI to CCA V2 sweep_unsold_tokens returns all base tokens to auction escrow (100% unsold since non-graduated)
  • All escrow tokens transferred to creator
  • Mint authority renounced
  • Bidders recover their quote currency directly from CCA V2 via exit_bid (non-graduated = full refund)

Emergency Withdrawal

A safety valve for when settlement stalls. If any settlement step fails permanently (e.g., external program upgrade breaks CPI compatibility), the timeout ensures funds are never locked forever.

  • Trigger: current_slot > finalized_slot + emergency_timeout_slots
  • Permissionless: Anyone can trigger. Creator does not need to sign.
  • Timeout is immutable: Snapshotted into LaunchConfig at creation time. Admin cannot change it retroactively.
  • Mint authority renounced even in the emergency path.

Idempotent Settlement

Settlement instructions are idempotent: if the state is already at or past the target state, they return Ok(()) without error. This means calling finalize_auction on an already-finalized launch is safe and does not revert, simplifying keeper bot implementation.