Design Decisions
Key architectural choices and why they were made.
FBA over Continuous Orderbook
Decision: Frequency Batch Auctions, not continuous matching.
Why: On EVM, continuous orderbooks create MEV extraction opportunities — bots race for time priority, sandwich trades, and front-run large orders. FBA eliminates intra-batch time priority and gives everyone the same clearing price. The trade-off is 60s latency per batch (configurable), which is acceptable for prediction markets where positions are held for minutes, not milliseconds.
Atomic Inline Settlement over Claim-Based Settlement
Decision: clearBatch() settles all orders atomically in a single transaction. No separate claim step.
Why: Single-transaction settlement eliminates the UX friction of a separate claim step. Users receive their fills, excess refunds, and minted positions immediately. Gas cost scales linearly with order count, bounded by SETTLE_CHUNK_SIZE = 400 per clearBatch call and MAX_ORDERS_PER_BATCH = 1600. Large batches are settled across multiple clearBatch calls with precomputed fills ensuring correctness.
Pyth price over ema_price
price over ema_priceDecision: Use spot price for settlement, not exponential moving average.
Why: Spot price gives clean, direct market semantics. A market asking "Will BTC be above $X at time T?" should resolve on the actual price at T, not a smoothed average. EMA would introduce lag and make resolution prices diverge from what traders observe on exchanges.
Trading Halt at Final Batch
Decision: Stop accepting orders when timeRemaining < batchInterval. No midpoint lock.
Why: The original PoC used a halfway-point lock (trading stops at 2.5 min in a 5-min market). This was arbitrary and wasted half the market duration. The new rule is simpler and maximizes trading time: the book stays open until the last complete batch can clear, then halts. Deterministic and fair.
ERC-1155 for Outcome Tokens
Decision: Multi-token ERC-1155, not ERC-20 per outcome.
Why: Deploying two ERC-20 contracts per market is expensive and creates address management overhead. ERC-1155 uses a single contract with deterministic token IDs (marketId * 2 for YES, marketId * 2 + 1 for NO). Cheaper deployment, simpler accounting, and tokens are still freely transferable.
Note: Current 5-minute markets use internal positions (
useInternalPositions = true) for efficiency. The ERC-1155 token system is retained for future market types that require transferable tokens (e.g., longer-duration markets, secondary market trading).
Segment Tree for Price Aggregation
Decision: Segment tree over naive iteration or Fenwick tree.
Why: Clearing requires finding where cumulative bid and ask volumes cross. Naive iteration over 99 ticks costs O(99) storage reads. A segment tree provides O(log 99) ≈ O(7) operations for both updates and prefix sum queries. Clober's LOBSTER research validates this approach for on-chain orderbooks with segmented trees that minimize SSTORE operations.
Finality Gate on Resolution
Decision: Two-step resolution with a 90-second finality period.
Why: A single-transaction resolution on BSC could theoretically be reorganized, changing the market outcome. By splitting into resolveMarket() (submit data) and finalizeResolution() (after the 90-second wait), we ensure the settlement price is economically final. The challenge window during the finality period lets anyone submit a better (earlier) Pyth update, enforcing the deterministic "earliest update wins" rule.
Open Submission by Default
Decision: Orders submitted publicly on-chain; private submission optional.
Why: Private transaction channels (BEP-322, NodeReal bundles) introduce infrastructure dependencies and trust assumptions. Open submission is the simplest, most composable baseline. Professional traders who want MEV protection can opt into private channels — the protocol works correctly either way.
BNB Chain over opBNB
Decision: Deploy on BSC mainnet, not opBNB L2.
Why: Gas is already cheap on BSC (~$0.008/order at 0.05 gwei). opBNB adds bridge friction (users must bridge from BSC), has a smaller ecosystem, charges nontrivial Pyth fees, and lacks the MEV infrastructure (BEP-322, bundle APIs) documented for BSC. The marginal gas savings don't justify the UX and ecosystem trade-offs.
Last updated