Skip to main content
Continuum v2 trades L and S tokens against native protocol venues - no external AMM. There are three, split by design: The split is the point: instant venues carry adverse-selection risk, so their depth and spread are sized for small trades. Large orders take the committed path, where the fill price is set after the commitment - latency arbitrage is impossible by construction, so size needs no cap and the spread is the thinnest of the three. The frontend routes for you: book trade for instant fills, auto-switching to committed mode above $5k notional (overridable). This page covers all three for builders.
Mint/redeem at NAV remains the canonical way to open or close a paired position - see Mint and Redeem. The venues here are for directional entries and exits.

Venue 1: instant book trade (pool_swap)

Each market has one native CLMM pool per side - (QQQ, long) and (QQQ, short) are separate pools. The whole book lives inline in the Pool account (up to 16 bins, no per-bin rent): asks are synth reserves above the base price, bids are cUSDC reserves below it. The keeper re-pins base_price to NAV whenever drift exceeds a per-market gate (see Book management). Bin geometry is 2-zone: fine core steps near NAV (e.g. QQQ 20bps × 3 core bins), then wide wings (300bps steps) that keep quoting through off-hours drift. A swap walks the bins in order - the output reflects real slippage, enforced by your min_out.

Accounts

TypeScript

To quote before swapping, read the Pool account and walk the bins yourself: bin k is priced at base_price · r^±k where r = 1 + step_bps/10_000 (core zone) switching to wing_step_bps beyond core_bins. See Reading state for a depth read. Standing depth is deliberately lean (~$5k bids / ≤$7.5k asks per side) - depth is sized to demand, not TVL, because toxic loss scales with deployed depth. If your size would eat through the book, use a committed order instead - that is what it exists for.

Venue 2: committed order (commit_swapsettle_swap)

The large-order path. You escrow the input into an order PDA; the fill executes at the first oracle print strictly after your commit, at NAV ± 0.10% (COMMIT_SPREAD_BPS = 10). Because the fill price is set after you committed, you cannot pick the protocol off with a stale quote - and the protocol cannot be picked off either, which is why:
  • No size cap, no window cap. Bounds are oracle health, the collateral floor, and keeper-provisioned inventory.
  • The thinnest spread of the three venues - a price set after the commitment carries zero adverse selection.
The lifecycle:
1

Commit

commit_swap(side, direction, amount_in, min_out, nonce) escrows your input (cUSDC for buys, synth for sells) into an escrow token account owned by the order PDA. The payout ATA must already exist - checked at commit so settlement can never strand on a missing account.
2

Settle (permissionless)

settle_swap fills at NAV(now) ± 10bps - valid only when the market’s TWAP timestamp is strictly newer than your commit and the oracle is healthy. The keeper cranks this (typical end-to-end 12-25s, bounded by the ~15s oracle push cadence), but anyone may settle. If the quoted output misses your min_out, the order is fully refunded - terminal, not a revert loop.
3

Cancel (after TTL)

If unsettled after 180 seconds (COMMIT_TTL_SECS), cancel_swap refunds unconditionally. It checks nothing else - no oracle, keeper, freeze, or market-active state. Escrowed funds are always recoverable after the TTL, regardless of protocol state.
Every terminal path (settle, refund, cancel) closes the order account and escrow - rent returns to you.

Order account

PDA seeds [b"order", user, market, nonce_le_bytes], clp program. nonce is client-supplied; use a timestamp or counter to allow concurrent orders.

Accounts: commit_swap

Accounts: settle_swap

Permissionless - the cranker signs and pays the tx fee, nothing more.

Accounts: cancel_swap

TypeScript

Events: OrderCommitted, OrderSettled (carries out, nav, base_price), OrderRefunded (min_out miss), OrderCancelled.
Mainnet prerequisite. Settlement currently prices off the keeper-relayed TWAP (market.user_twap_price). Before any mainnet deploy, settle_swap must read Pyth directly and enforce publish_time > order.created_at at that single code point.

Venue 3: instant oracle swap (clp_swap)

The original v2 path, retained for small instant trades: a fill at NAV ± a configured spread (30bps) from pre-stocked CLP inventory. No book, no slippage - but guarded hard, because an instant at-oracle fill is exactly what a latency arbitrageur wants:
  • Oracle health breakers - staleness (60s), confidence width, 25% deviation from the last accepted price.
  • Rolling notional window cap - bounds stale-price extraction per window. Committed orders bypass this and do not consume it.
  • Collateral floor - rejects fills that would quote into an under-collateralized market.
Accounts: user, user_usdc, user_synth, clp (PDA [b"clp", market_pda]), clp_vault, clp_synth, market, token_program. Args: (side, direction, amount_in, min_out) - same convention as the committed path. Inventory trades move already-outstanding, fully-backed tokens - supply and collateral are unchanged, only ownership moves.

Choosing a venue

A useful mental model: the book quotes a live price and charges you slippage for immediacy; the committed venue quotes a future price and charges you ~15 seconds of patience instead.

See also

Reading state

Pool books, NAV, pending orders - programmatically.

CLP program reference

Full instruction and account reference.

Book management

How the keeper keeps the books pinned to NAV.

Peg maintenance

Why prices stay honest without an arb bot.