Maker Price Band#
How Seesaw constrains where new resting maker orders can post on the order book. The price-band gate prevents orders from resting at unreasonable distances from the live midpoint (which would never realistically fill) without limiting taker behavior at all.
The authoritative behavior is defined by the ORDERBOOK specification (§"Maker price band") in the repository, and the band's safety properties are covered by formal (Kani) proofs in the program's verification suite.
What the gate does#
When a trader places a Limit or PostOnly order, the program computes a
[lo, hi] price band from the current orderbook midpoint and rejects the
order if its canonical price falls outside the band:
canonical_price < lo → OrderPriceOutOfBand (0x3014)
canonical_price > hi → OrderPriceOutOfBand (0x3014)
lo ≤ canonical_price ≤ hi → accepted
ImmediateOrCancel (IOC) orders bypass the gate — they never rest, so
they don't pollute the book regardless of what price the taker quotes
them at.
Why have a price band#
Two things the band protects against:
-
Dust spam: an attacker could post hundreds of resting orders at prices that will essentially never fill (1 bp, 9999 bps) just to bloat the book and waste matching CU. The band squeezes resting prices into a region that's actually plausible.
-
Stale-book whipsaw: when the book midpoint reflects real consensus, maker quotes far from mid are either mispriced or adversarial. The band lets the book bootstrap loose (during cold-start) and tighten as prices form.
The band does not affect:
- IOC takers (they always bypass)
- Settlement / oracle resolution (the band is about resting prices, not outcomes)
- Already-resting orders (the band gate runs at placement time only — resting orders that fall out of band due to midpoint drift stay resting)
How the band is computed#
The band is a pure function of the live order-book tops and their side counts —
it takes the best bid, bid count, best ask, and ask count and returns the
(lo, hi) price bounds:
compute_band(best_bid, bid_count, best_ask, ask_count) -> (lo, hi)
Constants#
The four constants that govern band width and clipping limits
(MAKER_BAND_BPS, STATIC_MIN_BPS_FOR_BAND, STATIC_MAX_BPS_FOR_BAND,
P_MAX) are listed with their canonical values in
Reference: Constants — Price Constants.
Two regimes#
1. Two-sided book (the normal case)#
When both sides have LIVE liquidity (bid_count > 0 AND best_bid > 0 AND ask_count > 0 AND best_ask < P_MAX), the band centers on the integer-floor midpoint and extends ±10%:
mid = floor((best_bid + best_ask) / 2)
lo = max(STATIC_MIN_BPS_FOR_BAND, mid - MAKER_BAND_BPS)
hi = min(STATIC_MAX_BPS_FOR_BAND, mid + MAKER_BAND_BPS)
All arithmetic is saturating — the function never panics on any
u16 input, a property verified exhaustively by a Kani proof.
Concrete example: book has best bid = 4500, best ask = 5500. Midpoint = 5000.
lo = max(100, 5000 - 1000) = 4000hi = min(9900, 5000 + 1000) = 6000- A maker quote at 5200 (52%) is accepted.
- A maker quote at 7500 (75%) is rejected.
- A maker quote at 3500 (35%) is rejected.
2. One-sided or empty book (bootstrap)#
When either side lacks LIVE liquidity, the band collapses to the static dust filter:
lo = STATIC_MIN_BPS_FOR_BAND (100)
hi = STATIC_MAX_BPS_FOR_BAND (9900)
This is intentional — a band can't be computed against a midpoint that doesn't exist. During cold start (or while a side is fully drained), the band degrades to "no price discipline beyond the 1%/99% dust filter."
Degenerate-book limitation (BY DESIGN, not a defect): On a one-sided or empty book, the band widens to roughly the full
[100, 9900]window (~98% wide). The first maker(s) to post a two-sided quote anchor the price region all subsequent liquidity is gated against.This is intentional. Final market outcomes are oracle-driven, so a skewed early band carries no settlement / fund-loss risk. The band only affects which resting prices are accepted before the book is two-sided.
Why the sentinel checks matter#
The band computation checks both the *_count == 0 predicates AND the
sentinel values (best_bid == 0, best_ask >= P_MAX). Both are necessary
because retained non-active settlement markers and ExpiredClaimable slots can
remain in the side counts even after the best-price field has been reset to its
sentinel.
Without the sentinel check, a side containing only retained non-active slots would anchor the midpoint at half-book and brick legitimate makers near the true price.
Where the gate runs#
The gate runs inside the place-order flow. It fires:
- After canonical conversion (NO orders are flipped to canonical YES-book coordinates).
- After tick alignment (the canonical price is rounded to the configured tick).
- Before the match step (so rejected orders never touch matching state).
What this means for you#
The on-chain gate is authoritative — a client preview is advisory only.
If your order is rejected with OrderPriceOutOfBand (0x3014), the midpoint
has moved; refresh the book and recompute the band before resubmitting.
- For placing orders step-by-step, see Placing Orders.
- To reproduce the band formula programmatically (e.g., in a bot or custom client), see the SDK docs.
End-to-end behavior#
The web and mobile clients are covered by end-to-end tests that exercise both:
- The client-side warning when the trader picks an out-of-band price.
- The program-side
OrderPriceOutOfBandrejection when the client-side warning is disabled, confirming the on-chain gate is the authoritative check.
Dev bypass#
The clients accept a development-only flag that disables the client-side warning (used by the end-to-end tests to drive a placement all the way to the on-chain reject). The program-side gate is never bypassed — even with the client warning off, the on-chain rejection still fires. This is a client UX bypass, not a protocol bypass, and the flag is stripped from production builds.
Invariants#
The price-band invariants (INV-BAND-1 through INV-BAND-6) are part of the canonical Protocol Invariants catalog.
For the full invariant catalog covering vault solvency, order-book ordering, settlement, fees, and the price-band subsystem, see security/invariants.md.
Related docs#
- The ORDERBOOK specification (§"Maker price band") in the repository — authoritative spec
how-it-works/orderbook— orderbook matching mechanicshow-it-works/slippage— how taker fills are previewed (IOC orders bypass the band)for-traders/placing-orders— user-facing placement guidesecurity/invariants— full invariant catalog
Price-band invariants (INV-BAND-1 through INV-BAND-6) have been consolidated into the canonical invariant catalog. See security/invariants.md — Price-Band Invariants for the authoritative definitions, formal statements, and Kani proof citations.