Data Structures

This document details the core data structures used throughout the CLOB system.

Order

The fundamental unit of trading in the system.
struct Order {
    address user;        // Order owner
    uint256 id;          // Unique order identifier
    uint256 quantity;    // Total order quantity
    uint256 filled;      // Amount already filled
    uint256 price;       // Limit price (0 for market orders)
    uint256 expiry;      // Expiration timestamp (0 = no expiry)
    Status status;       // Current order status
    OrderType orderType; // Limit or Market
    Side side;           // Buy or Sell
}

Field Details

FieldTypeDescription
useraddressWallet address that owns the order
iduint256Unique identifier assigned on creation
quantityuint256Original order size in base currency units
filleduint256Cumulative filled amount
priceuint256Limit price scaled by PRICE_SCALE
expiryuint256Unix timestamp; 0 means no expiration
statusStatusCurrent lifecycle status
orderTypeOrderTypeLimit (0) or Market (1)
sideSideBuy (0) or Sell (1)

Derived Values

// Remaining quantity to fill
uint256 remaining = order.quantity - order.filled;

// Whether order is still active
bool isActive = order.status == Status.Open ||
                order.status == Status.PartiallyFilled;

// Quote currency amount for limit order
uint256 quoteAmount = (order.quantity * order.price) / PRICE_SCALE;

Pool / PoolKey

Identifies a trading pair in the system.
struct PoolKey {
    address baseCurrency;   // Token being traded
    address quoteCurrency;  // Token used for pricing
}

Pool Identification

Pools are uniquely identified by their currency pair. The system enforces a canonical ordering to prevent duplicate pools:
// Pool ID derivation
bytes32 poolId = keccak256(abi.encode(baseCurrency, quoteCurrency));

Example Pools

BaseQuoteMarket
WETHUSDCETH/USDC
WBTCUSDCBTC/USDC
ARBWETHARB/ETH

TradingRules

Defines the trading parameters for a pool.
struct TradingRules {
    uint256 minTradeAmount;     // Minimum trade size
    uint256 minAmountMovement;  // Quantity tick size
    uint256 minPriceMovement;   // Price tick size
    uint256 minOrderSize;       // Minimum order size
    uint256 maxOrderSize;       // Maximum order size (0 = unlimited)
}

Field Details

FieldDescriptionExample
minTradeAmountSmallest executable trade0.001 ETH
minAmountMovementQuantity must be multiple of this0.0001 ETH
minPriceMovementPrice must be multiple of this0.01 USDC
minOrderSizeSmallest allowed order0.01 ETH
maxOrderSizeLargest allowed order1000 ETH

Validation

Orders are validated against trading rules:
// Price must be on valid tick
require(price % rules.minPriceMovement == 0, "InvalidPriceIncrement");

// Quantity must be on valid tick
require(quantity % rules.minAmountMovement == 0, "InvalidQuantityIncrement");

// Order size must be within bounds
require(quantity >= rules.minOrderSize, "OrderTooSmall");
require(rules.maxOrderSize == 0 || quantity <= rules.maxOrderSize, "OrderTooLarge");

OrderQueue

Manages orders at a single price level.
struct OrderQueue {
    uint256 head;       // First order ID in queue
    uint256 tail;       // Last order ID in queue
    uint256 count;      // Number of orders
    uint256 volume;     // Total volume at this price
}

Queue Operations

Linked List Navigation

Orders within a queue are linked:
// Order links for queue traversal
mapping(uint256 => uint256) nextOrder;  // orderId => next orderId
mapping(uint256 => uint256) prevOrder;  // orderId => prev orderId

Enums

Side

enum Side {
    Buy,    // 0 - Bid side
    Sell    // 1 - Ask side
}

OrderType

enum OrderType {
    Limit,   // 0 - Limit order with specified price
    Market   // 1 - Market order executed at best prices
}

Status

enum Status {
    Open,             // 0 - Order is active and unfilled
    PartiallyFilled,  // 1 - Order is partially filled
    Filled,           // 2 - Order is completely filled
    Cancelled         // 3 - Order was cancelled
}

TimeInForce

enum TimeInForce {
    GTC,      // 0 - Good Till Cancel
    IOC,      // 1 - Immediate or Cancel
    FOK,      // 2 - Fill or Kill
    PostOnly  // 3 - Add liquidity only
}

SelfTradePreventionMode

enum STPMode {
    None,         // 0 - Allow self-trades
    CancelTaker,  // 1 - Cancel incoming order
    CancelMaker,  // 2 - Cancel resting order
    CancelBoth    // 3 - Cancel both orders
}

QuoteResult

Returned by quote functions to preview trade execution.
struct QuoteResult {
    uint256 expectedAmountOut;   // Expected output amount
    uint256 totalQuoteAmount;    // Total quote currency involved
    uint256 executionPrice;      // Execution price
    uint256 avgExecutionPrice;   // Average execution price
    uint256 priceImpact;         // Price impact in basis points
    uint256 fee;                 // Trading fee
    bool executable;             // Whether order can execute
    string message;              // Status/error message
}

Usage Example

QuoteResult memory quote = router.getQuote(
    baseCurrency,
    quoteCurrency,
    OrderType.Market,
    Side.Buy,
    1 ether,  // quantity
    0         // price (0 for market orders)
);

// Check if executable
if (quote.executable) {
    // Place order with slippage protection
    uint256 minOut = quote.expectedAmountOut * 99 / 100; // 1% slippage
    router.placeMarketOrder(pool, 1 ether, Side.Buy, user, minOut);
}

PriceVolume

Represents aggregated data at a price level.
struct PriceVolume {
    uint256 price;   // Price level
    uint256 volume;  // Total volume at this price
}

Usage

// Get best bid
PriceVolume memory bestBid = router.getBestPrice(
    baseCurrency,
    quoteCurrency,
    Side.Buy
);

// Get depth (next N price levels)
PriceVolume[] memory asks = router.getNextBestPrices(
    pool,
    Side.Sell,
    0,     // start from best
    10     // get 10 levels
);

BatchOrder

Used for batch order operations.
struct BatchOrder {
    PoolKey pool;           // Trading pair
    uint256 price;          // Limit price
    uint256 quantity;       // Order size
    Side side;              // Buy or Sell
    TimeInForce timeInForce; // Order duration
}

Batch Result

struct BatchOrderResult {
    uint256 orderId;   // Assigned order ID (0 if failed)
    bool success;      // Whether order succeeded
    string message;    // Error message if failed
}

Constants

Price and Amount Scaling

// Price scaling factor
uint256 constant PRICE_SCALE = 1e18;

// Fee denominator (for basis point precision)
uint256 constant FEE_UNIT = 1_000_000;

Status Values

// Order status progression
// Open -> PartiallyFilled -> Filled
//   |           |
//   v           v
// Cancelled  Cancelled

Storage Mappings

OrderBook Storage

// Order storage
mapping(uint256 => Order) orders;

// Price trees (Red-Black)
RedBlackTree buyTree;   // Descending order (best = highest)
RedBlackTree sellTree;  // Ascending order (best = lowest)

// Order queues at each price
mapping(uint256 => OrderQueue) buyQueues;   // price => queue
mapping(uint256 => OrderQueue) sellQueues;  // price => queue

// User order tracking
mapping(address => uint256[]) userOrders;   // user => orderIds

BalanceManager Storage

// Available balances
mapping(address => mapping(address => uint256)) balances;
// user => currency => amount

// Locked balances
mapping(address => mapping(address => mapping(address => uint256))) lockedBalances;
// user => operator => currency => amount