Phoenix: the crankless on-chain order book, and the perps extension
Phoenix is Solana's crankless on-chain limit order book — atomic fills, no separate crank, all in one Rust program. Here's the market architecture and design.
devrels.xyz/a/82short linkPhoenix is the cleanest fully on-chain limit order book on Solana. Its headline innovation: it's crankless. Earlier on-chain order books (Serum/OpenBook) needed a separate "crank" process to match resting orders and settle fills. Phoenix settles atomically inside the taker's own transaction — no crank, no separate settlement step, no MEV window between match and settle.

Why the crank was a problem
Serum-style books worked like this: makers post orders; takers post orders; a permissionless "crank" transaction later matches them and pushes fills to an event queue; another step settles balances. Three issues:
- Latency. Your fill wasn't final until the crank ran — could be several slots later.
- MEV. The gap between match and settle was a window for extraction.
- Liveness dependence. If nobody cranked, the book stalled.
Phoenix's crankless design
Phoenix collapses match + settle into the taker's instruction. When you send a market order (or a marketable limit order):
Taker submits an order in transaction T:
1. Phoenix walks the resting order book in-program
2. Matches against resting maker orders, computing fills
3. Atomically credits/debits both the taker AND the matched makers'
balances — all inside transaction T
4. Resting orders that got filled are removed from the book
5. Any unfilled taker remainder rests on the book (for limit) or
is cancelled (for IOC/market)
No crank. No event queue to drain. Fill is final when T confirms.The makers don't need to be online or sign anything at fill time — their resting orders already committed their funds to the market. Phoenix moves the funds on their behalf when a taker crosses their price.
The account model
// Market account — the order book itself
pub struct MarketHeader {
pub base_mint: Pubkey, // e.g. SOL
pub quote_mint: Pubkey, // e.g. USDC
pub base_vault: Pubkey, // token vault holding deposited base
pub quote_vault: Pubkey, // token vault holding deposited quote
pub base_lot_size: u64, // smallest tradeable base increment
pub quote_lot_size: u64, // smallest price increment
pub tick_size: u64,
pub authority: Pubkey,
pub fee_recipient: Pubkey,
// followed by the bids tree + asks tree + trader registry (in account data)
}
// Seat — a trader's authorization to place orders on a market
// (Phoenix gates makers via seats; takers can trade without one)
pub struct Seat {
pub market: Pubkey,
pub trader: Pubkey,
pub approval_status: SeatApprovalStatus,
}The order book lives entirely in the market account's data — a pair of red-black-tree-like structures for bids and asks, plus a trader registry tracking each participant's locked and free balances. Reading the book is a single getAccountInfo + deserialize.
Placing orders
import { Client, Side, OrderPacket } from "@ellipsis-labs/phoenix-sdk"
import { Connection, Keypair } from "@solana/web3.js"
const conn = new Connection("https://api.mainnet-beta.solana.com")
const client = await Client.create(conn)
const market = client.marketStates.get(marketAddress)!
// A limit order: rest on the book at a price
const limitOrder: OrderPacket = {
__kind: "Limit",
side: Side.Bid,
priceInTicks: market.floatPriceToTicks(142.50),
numBaseLots: market.rawBaseUnitsToBaseLots(10), // 10 SOL
selfTradeBehavior: 0,
matchLimit: null,
clientOrderId: 0,
useOnlyDepositedFunds: false,
}
const placeIx = client.createPlaceLimitOrderInstruction(limitOrder, marketAddress, trader.publicKey)
// An immediate-or-cancel market buy: cross the book now
const marketOrder: OrderPacket = {
__kind: "ImmediateOrCancel",
side: Side.Bid,
priceInTicks: null, // null = take any price
numBaseLots: market.rawBaseUnitsToBaseLots(5),
minBaseLotsToFill: 0,
numQuoteLots: 0,
minQuoteLotsToFill: 0,
selfTradeBehavior: 0,
matchLimit: null,
clientOrderId: 0,
useOnlyDepositedFunds: false,
}Orders are priced and sized in lots — integer multiples of the market's base_lot_size and quote_lot_size. This keeps all arithmetic in integers (no float drift in the matching engine) and bounds the precision of the book.
Reading the live book
const ladder = market.getUiLadder(10) // top 10 levels each side
console.log("bids:", ladder.bids) // [{ price, quantity }, …]
console.log("asks:", ladder.asks)
// Or get the L3 (per-order) view
const book = market.getLadder()The perps extension
Phoenix's core is a spot CLOB. The perps layer builds the same crankless matching primitive into a derivatives market — positions instead of spot balances, funding payments instead of settlement, mark-price from the book combined with an oracle. The order-matching engine underneath is the same atomic, crankless design; the difference is what gets settled (position deltas + funding vs token balances).
Update (July 2026): quietly one of the busiest programs on Solana
The perps program (EtrnLzgbS7nMMy5fbD42kXiUzGg8XQzJ972Xtk1cjWih) now ranks #6 on the entire chain by instruction invocations — 37.7 million per day per ProgramWatch's leaderboard, more than Jupiter v6. That volume is the crankless design doing its job: every match settles inside the taker's transaction, and funding plus market-maker quote churn ring the program constantly.
The odd footnote: you wouldn't know any of this from an explorer. The program carries no on-chain IDL, no verified build, and no label in most program databases — only Solana Compass's registry ties the address to Phoenix. A top-six program that passes for anonymous bytecode is the clearest argument we've seen for registering verified builds and posting IDLs on-chain.
Why this still matters
- It proved fully on-chain CLOBs are viable. The conventional wisdom was "order books need an off-chain sequencer." Phoenix showed you can do it on-chain on Solana with atomic settlement.
- No MEV from match/settle gaps. The atomic fill means there's no window to sandwich between matching and settlement.
- Composable. Because fills are atomic, another program can CPI into Phoenix and know the fill is final within the same transaction — critical for aggregators and structured products.
References
Phoenix is the reference design for crankless on-chain order books. Whether you trade on it, build on it, or just want to understand how a fully-on-chain CLOB settles atomically — the crankless model above is the core idea.
Keep reading
A dog airdrop after FTX became Solana's loudest cultural brand — then shipped swaps, rewards, bot volume, launchpads, and regulated wrappers. Here is the stack, the fee flywheel, and why "just a meme" is lazy ecosystem analysis.
Superstate ships tokenized Treasuries (USTB) and crypto carry (USCC) on Solana as Token-2022, plus Opening Bell equities and FundOS for asset managers. For builders: public NAV/yield endpoints, signed partner APIs, Solana allowlist thaw, and onboarding that returns a partially signed SVM transaction.
After teasing a glowing globe for two and a half years, World revealed itself on July 1 as a prediction market protocol on Solana, shipping as the Predictions tab inside Phantom. Positions are tokens in your own wallet, payouts push automatically in CASH, and Chainlink drives resolution. Under the hood it is not an order book or an AMM: it is a complete-set vault plus an RFQ maker network routed through DFlow. Here is the architecture, the Polymarket comparison, and the developer reality.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
