Order Book Design#
Seesaw matches trades through a fully on-chain order book. Two design choices define how it works: every market uses a single canonical order book shared by YES and NO, and that book lives in a single fixed-size account on Solana.
One book for YES and NO#
A binary market has two outcomes, which naturally suggests two order books — one for YES shares and one for NO shares. Seesaw uses one instead, because in a binary market the two sides are economically identical.
Buying YES at price p is the same trade as selling NO at price 1 − p:
Because the trades are equivalent, all liquidity can live in a single book of
YES bids and asks. NO orders are converted to their YES equivalent by
price complement (q → 10000 − q) before they rest. The full conversion
rules and matching mechanics are in Order Book.
Concrete example — all four order types at the same economic position:
| You place | At price | Rests as | At price |
|---|---|---|---|
| Buy YES | 6000 | Bid | 6000 |
| Sell YES | 6000 | Ask | 6000 |
| Buy NO | 4000 | Ask | 6000 |
| Sell NO | 4000 | Bid | 6000 |
Why this matters#
- Unified liquidity. All orders concentrate in one book, producing tighter spreads and better price discovery than two fragmented books would.
- Consistent pricing. YES at 60% and NO at 40% are always consistent by construction — there is no second book that can drift out of line, so no cross-book arbitrage is needed to keep them aligned.
- Simpler, deterministic matching. A single matching engine runs against a single book.
The trade-off is that NO orders are mirrored across the midpoint, so tick rounding applies to the converted price (a Buy NO at 4050 becomes an Ask at 5950, which then rounds to the tick). Clients show the effective price after rounding so the behavior is transparent. The SDK performs the conversion for you, so you can work in the four intuitive order types.
After conversion, the standard order-book invariant holds: the best bid is always below the best ask when both exist.
Complementary matching only#
The book enforces complementary matching: BuyYES orders match only against SellYES orders, and SellNO orders match only against BuyNO orders. After conversion to canonical form, this is automatic — bids match asks on the single YES book. There is no "cross-matching" where a BuyYES order directly meets a BuyNO order; they sit on the same side after conversion and never fill each other.
This ensures the economic symmetry holds: every fill creates exactly one YES payout and one NO payout, both fully collateralized.
Stored in a single account#
The entire book for a market lives in one fixed-size account (the
OrderbookAccount, derived at ["seesaw", "orderbook", market_pubkey]). It
holds up to 63 bids and 63 asks — 126 resting orders — as flat, sorted
arrays of fixed-size order records.
OrderbookAccount (10,240 bytes)
├── Header (64 bytes) discriminator, next order id, best bid/ask, counts, bump
├── Bids (5,040 bytes = 63 orders × 80 bytes, sorted high → low)
├── Asks (5,040 bytes = 63 orders × 80 bytes, sorted low → high)
└── Padding
Each order is an 80-byte record holding its id, owner, price, remaining and original quantity, timestamp, side, and active flag.
Matching iterates from the top of the opposing side using price-time priority — best price first, then earliest timestamp:
Place a bid @ 6500:
1. Scan asks from lowest price upward.
2. While the best ask ≤ 6500, fill at the ask price.
3. Stop when no ask is matchable or the order is fully filled.
4. Rest any remainder in the bids array at its sorted position.
Asks match symmetrically against the bids.
Why a single account#
Solana requires every account a transaction touches to be declared upfront, and caps each instruction at a fixed compute budget. A single self-contained book fits those constraints cleanly:
- One account to read and write. Matching needs no cross-account calls, and a transaction only declares the orderbook, market, position, and vault.
- Predictable, bounded compute. Matching scans at most 63 orders per side, and inserts/removals shift a small, fixed-size array — fast in Solana's linear memory model and well within the compute budget. There is no tree to rebalance.
- Fixed, reclaimable rent. The account is always the same size regardless of how many orders rest in it, and the rent is returned when the market closes.
- Zero-copy access. The book is read directly from account bytes with no deserialization step, which keeps reads cheap for both the program and off-chain consumers.
The deliberate cost is capacity: 126 resting orders per market. For short-duration markets, where orders are placed and filled within minutes and expire with the market, this is ample — a side simply rejects new resting orders once it is full. Post-only and immediate-or-cancel order types help keep the resting count low.
Alternatives we did not take#
- Two separate books (one each for YES and NO) would fragment liquidity and require an arbitrage mechanism to keep the two priced consistently.
- A signed single share (positive = YES, negative = NO) makes balances and solvency harder to reason about.
- An AMM trades worse for large orders on binary outcomes, exposes liquidity providers to loss, and is easier to manipulate than an order book.
- A tree- or slab-based book across many accounts adds far more capacity than short markets need, at the cost of per-node account access, unpredictable rent, and significantly more complexity.
- An off-chain matcher would reintroduce a trusted intermediary and censorship/front-running risk, which contradicts Seesaw's permissionless design.
For the user-facing walkthrough of placing and matching orders, see How It Works → Order Book. For fill estimation and price impact, see How It Works → Slippage. For where collateral lives at each step, see How It Works → Flow of Funds.