Open Interest Implementation Notes
Overview
This document provides implementation context for the Open Interest Beyond Current Pool Price orderbook architecture documented in open-interest-beyond-price.md.
Architecture Summary
The orderbook implementation is a price-gated limit order layer built on top of the concentrated liquidity AMM. Key characteristics:
Not a Traditional CLOB
This is not a continuous limit order book (CLOB) with active matching. Instead:
- AMM-gated execution: Orders only trigger when swap flow would push the AMM spot price past their level
- No matching engine: No separate matching loop or order processor
- Composable: Orders and AMM liquidity are both routable by the protocol router
Core Data Structure: SumTree (Fenwick Tree)
The orderbook uses a Binary Indexed Tree (Fenwick Tree) over discrete price ticks to achieve O(log N) operations:
// Two separate trees: buy side and sell side
mapping(int24 tick => uint256) private buyTree;
mapping(int24 tick => uint256) private sellTree;
// Per-tick order information
mapping(int24 tick => TickInfo) private ticks;
Benefits:
- O(log N) to find next crossing tick
- O(log N) to update volumes
- O(log N) for prefix sum queries
- Bounded gas cost regardless of orderbook size
Key Design Decisions
1. Deferred Settlement (Pull-based Claims)
Decision: Orders don't immediately transfer tokens on fill. Instead, fills accrue to "claimable" balances that users claim later.
Rationale:
- Gas efficiency: One SSTORE per user per swap instead of transfer per order
- Reentrancy safety: No external calls during swap execution
- Bounded gas: Swap execution gas is predictable regardless of order count
Implementation:
mapping(address => mapping(address => uint256)) public claimable;
2. Aggregate Per Owner (Not Per Order)
Decision: Store orders aggregated by (tick, owner) rather than individual order structs.
Rationale:
- DoS resistance: Can't spam orderbook with thousands of tiny orders
- Gas savings: One storage slot per (tick, owner) combination
- Simple accounting: Pro-rata allocation within ticks
Trade-off: Lose per-order granularity and strict FIFO within tick
3. Tick Discretization
Decision: Orders can only be placed at fixed tick intervals (e.g., every 10 bps).
Rationale:
- Concentrates liquidity: Forces orders to cluster at predictable levels
- Reduces state space: Bounds number of possible price levels
- Prevents pennying: Users can't place orders 0.01% ahead of each other
Parameters:
- Standard RWA pools: 10 ticks (~10 bps spacing)
- Volatile pools: 50-100 ticks (~50-100 bps)
4. Max Ticks Per Swap
Decision: Hard-cap the number of ticks that can be crossed in a single swap (16-32).
Rationale:
- Gas budget protection: Prevents DoS via forcing many tick crossings
- Block gas limit: Ensures swaps never exceed block gas limit
- Predictable costs: Users know worst-case gas for swaps
Fallback: If more ticks need crossing, remaining flow continues on AMM curve
5. Price Priority + Configurable Time Priority
Decision: Strict price priority, but time priority within tick is configurable (pro-rata or FIFO).
Pro-rata (recommended):
mapping(int24 tick => mapping(address owner => uint256 amount)) private ordersByOwner;
FIFO (optional):
struct Order {
address owner;
uint128 amount;
bytes32 next; // Linked list
}
Recommendation: Use pro-rata for V1 (gas-efficient, DoS-resistant), consider hybrid k-FIFO later
Integration with Existing Components
With CL AMM
- Execution order: Orderbook ticks execute before AMM curve
- Price path: AMM curve determines which ticks to cross
- Fallback: Any flow not absorbed by orders continues on AMM
- Atomic: Both orderbook and AMM execution in single transaction
With Minting (Open Interest)
- Case B solution: Provides buy orders above current price for when
acquisition < pool price - Forward demand: Issuers see committed capital at various price levels
- Mint execution: New tokens preferentially fill orderbook buy orders above acquisition price
See Open Interest (Minting) for details.
With Router
- Quote function: Router simulates orderbook execution to estimate output
- Hybrid routing: Router can split flow between orderbook and AMM optimally
- Composability: Orderbook is just another liquidity source for aggregators
Implementation Phases
Phase 1: Core Infrastructure (MVP)
Non-negotiables:
- Fenwick tree over ticks
- Aggregate per owner (DoS resistance)
- Deferred claiming
- Price-time priority (pro-rata within tick)
- Batch operations for market makers
Gas budget: ~60-100k per order placement, ~10-20k per tick crossed
Phase 2: Enhanced UX
Strongly recommended: 6. Minimum order size enforcement ($100+) 7. Max ticks per swap limit (16-32) 8. Order expiry timestamps 9. Claim-for-other incentive (0.1% bounty)
Phase 3: Advanced Features
Nice-to-have: 10. Commit-reveal for privacy 11. ZK-proof integration 12. Hybrid FIFO+pro-rata matching 13. Cross-chain orderbook support
Security Considerations
DoS Attack Vectors
Attack 1: Order spam
- Mitigation: Minimum order size ($100+), tick spacing, expiry timestamps
Attack 2: Many tiny orders spread across ticks
- Mitigation: Per-owner aggregation (not per-order), max ticks per swap
Attack 3: Front-running order placement
- Mitigation: Accept MEV as unavoidable, ensure deterministic execution
Manipulation Resistance
Price manipulation:
- Orders execute at fixed tick prices (no slippage within tick)
- AMM curve determines which ticks cross (can't force arbitrary execution)
- Mark-to-Truth auctions backstop for sustained mispricing
Orderbook spoofing:
- Orders must be fully funded (no leveraged/margin orders in V1)
- Cancellation requires gas cost (deters fake orders)
Gas Optimization Techniques
1. Sparse Tree Storage
Only store ticks with active orders:
mapping(int24 tick => TickInfo) private ticks;
// Empty ticks consume zero storage
2. Batch Tree Updates
When placing multiple orders, batch SumTree updates:
function placeMany(...) external {
// Accumulate updates
for (...) {
pendingUpdates[tick] += amount;
}
// Apply to tree once
for (tick in pendingUpdates) {
buyTree.add(tick, pendingUpdates[tick]);
}
}
3. Storage Reclamation
Delete empty ticks to receive gas refunds:
if (info.quoteLiquidity == 0 && info.baseLiquidity == 0) {
delete ticks[tick];
}
4. Claim Batching
Allow claiming multiple tokens in one transaction:
function claimMany(address[] calldata tokens) external {
for (token in tokens) {
// Single call to claim each
}
}
Testing Strategy
Unit Tests
- SumTree operations (add, subtract, prefix sum, find next)
- Order placement (valid/invalid ticks, minimum sizes)
- Order cancellation (partial fills, full refunds)
- Tick crossing (volume debit, price application)
- Claiming (single token, multiple tokens, expiry)
Integration Tests
- Swap execution crossing multiple ticks
- Hybrid AMM + orderbook routing
- Interaction with minting mechanisms
- Mark-to-Truth auction impact on orders
Stress Tests
- 1000+ orders across 100+ ticks
- Large swap crossing max ticks (16-32)
- Concurrent order placement and cancellation
- Gas profiling for all operations
Attack Simulations
- DoS via order spam
- Front-running order placement
- Orderbook spoofing (fake orders)
- MEV extraction strategies
Monitoring Metrics
Health Metrics
- Active orders: Total number of unfilled orders
- Active ticks: Number of ticks with orders
- Total liquidity: Sum of all order volumes
- Fill rate: % of orders that execute vs cancel
Performance Metrics
- Gas per operation: Placement, cancellation, crossing tick
- Ticks per swap: Average number of ticks crossed
- Time to fill: Distribution of order lifetime before fill
- Claim latency: Time between fill and claim
Market Quality Metrics
- Spread: Distance between best bid and best ask
- Depth: Volume within X% of mid price
- Imbalance: Ratio of buy vs sell order volume
- Execution quality: Orders filling at exact tick prices
Future Enhancements
Privacy
Commit-reveal orders:
- Hide order details until execution
- Prevents front-running and information leakage
- Trade-off: Reduces router visibility
ZK-proof orders:
- Fully private order placement
- Homomorphic tree updates
- Expensive cryptographic overhead
Cross-chain
L2 orderbook, L1 settlement:
- Place orders on cheap L2 (Arbitrum, Base)
- Execute fills on L1 (where AMM liquidity lives)
- Bridge claims back to L2
Multi-chain aggregation:
- Orders on multiple chains
- Unified orderbook view
- Cross-chain execution via bridges
Advanced Matching
Hybrid k-FIFO:
- First k orders at tick get FIFO priority
- Remaining orders fill pro-rata
- Balance fairness and gas costs
Price-time-size priority:
- Large orders get slight priority
- Incentivize meaningful liquidity provision
- Prevent penny-sized order spam
Related Documentation
- Open Interest Beyond Current Pool Price — Full technical specification
- Limit Orders — User-facing limit order interface
- Open Interest (Minting) — Integration with supply management
- CL AMM Primer — Underlying AMM infrastructure
- Liquidity Management — Professional market making strategies
References
Data structures:
- Fenwick Tree (Binary Indexed Tree): O(log N) prefix sums and updates
- Segment Tree: Alternative with range query/update support
Similar implementations:
- Uniswap V3 concentrated liquidity (single-tick positions)
- Traditional exchange limit order books (continuous matching)
- Hybrid orderbook-AMM designs (discrete + continuous liquidity)
Key insight: Treat the AMM as a price oracle and fallback liquidity source, with the orderbook as a capital-efficient interception layer at price boundaries.