Orderbook

The Orderbook precompile is the on-chain execution surface for native markets — both spot and perpetual. The same contract, calls, and balances are shared across both market types; a market's behavior is determined by the MarketType set at creation.

Use it for placing/canceling/updating orders, depositing/withdrawing funds, opening leveraged perpetual positions, and reading balances and order state.

Orderbook precompile address: 0x50d0000000000000000000000000000000000002

Orders are identified by the submitOrder tx hash. Wherever a call references an existing order — cancel(canceledOrder, …), update(updatedOrder, …), the batch getOrders(txHashes, …) read — pass the transaction hash returned by eth_sendRawTransaction when the order was originally submitted. The same value is echoed as tx_hash on ob_getOrders. See Transaction hashes as identifiers in the API reference index for the general rule.

Batch envelope

submitBatch packs several single-intent calls (1–64) into a single signed transaction that lands atomically in one auction tick. Each entry in inner is the full ABI-encoded calldata of a single-intent function (submitOrder, cancel, update, submitTrigger, deposit, …) — encoded exactly as a standalone call, including its 4-byte selector. Every sub-intent must carry the same deadline (the uniform-deadline invariant), and nested batches are rejected. For the full rules and a worked example, see Submit a batch order.

Solidity interface (ABI)

/**
 * @title Orderbook
 * @notice A central limit order book for trading assets.
 * @dev Handles order placement, cancellation, and fund management.
 */
contract Orderbook {

    enum Side { Buy, Sell }
    enum OrderType { Limit, Market }
    enum MarketType { Spot, Perp }

    // --- Events ---

    event SolutionExecuted(
        bytes32 indexed orderbookId,
        uint128 deadline,
        uint256 clearingPrice,
        uint256 totalVolume,
        uint256 newOrdersCount
    );

    // --- Order Management ---

    /**
     * Submits a new order to the orderbook.
     * The direction of the trade (Bid/Ask) is determined by the sign of the size.
     * @param orderbookId The unique identifier of the specific market (e.g., ETH-USDC).
     * @param size The size of the order. Positive (+) for Buy/Bid, Negative (-) for Sell/Ask.
     * @param price The limit price for the order.
     * @param orderType The order type (Limit or Market).
     * @param deadline The timestamp limit for this order to be included in a batch in microseconds. Must be a multiple of the market's `auction_interval`.
     * @param ttl The "Time To Live" duration in microseconds; how long the order remains active in the book.
     * @param reduceOnly If true, this order will only reduce an existing position. Perp markets only.
     * @param ioc If true, the order is Immediate-Or-Cancel: any unmatched portion is cancelled at the end of the batch instead of resting on the book.
     */
    function submitOrder(
        bytes32 orderbookId,
        int256 size,
        uint256 price,
        OrderType orderType,
        uint128 deadline,
        uint128 ttl,
        bool reduceOnly,
        bool ioc
    ) public {}

    /**
     * @notice Cancels an existing open order.
     * @param orderbookId The unique identifier of the market the order belongs to.
     * @param canceledOrder The unique identifier/`tx_hash` of the original `submitOrder` transaction
     *        (also exposed as `tx_hash` on `ob_getOrders`).
     * @param deadline The Unix timestamp after which this cancellation request is invalid in microseconds. Must be a multiple of the market's `auction_interval`.
     */
    function cancel(
        bytes32 orderbookId,
        bytes32 canceledOrder,
        uint128 deadline
    ) public {}

    /**
     * @notice Updates an existing open order.
     * @param orderbookId The unique identifier of the market the order belongs to.
     * @param updatedOrder The unique identifier/`tx_hash` of the original `submitOrder` transaction
     *        (also exposed as `tx_hash` on `ob_getOrders`).
     * @param newSize The new size for the order.
     * @param newPrice The new price for the order.
     * @param token The token used to cover any additional collateral required by the update.
     * @param deadline The Unix timestamp after which this update is invalid in microseconds. Must be a multiple of the market's `auction_interval`.
     */
    function update(
        bytes32 orderbookId,
        bytes32 updatedOrder,
        uint256 newSize,
        uint256 newPrice,
        address token,
        uint128 deadline
    ) public {}

    // --- Data Retrieval ---

    /**
     * @notice Retrieves the deposited balance of a token for a specific account.
     * @param token The address of the ERC20 token to check.
     * @param account The address of the account to check.
     * @return The current balance of the token held by the account within the exchange.
     */
    function balanceOf(address token, address account) public view returns (uint256) {}

    /**
     * @notice Retrieves the deposited balance of the caller for a specific token.
     * @param token The address of the ERC20 token to check.
     * @return The current balance of the token held by the caller within the exchange.
     * @deprecated Use balanceOf(address token, address account) instead.
     */
    function getBalance(address token) public view returns (uint256) {}

    /**
     * @notice Batches retrieval of order details by their transaction hashes.
     * @param orderbookId The identifier of the market.
     * @param txHashes An array of transaction hashes representing the orders to fetch.
     * @return An array of order structs containing:
     * - hash: The unique order identifier.
     * - side: The order side (Buy/Sell).
     * - status: The current status (e.g., Open, Filled, Canceled).
     * - remainingBase: The amount of base asset left to fill.
     * - price: The limit price.
     * - startTs: Timestamp when the order was included in the orderbook.
     * - endTs: Timestamp when the order expires.
     * - filledBase: Amount of base asset already filled.
     * - filledQuote: Amount of quote asset spent/received.
     */
    function getOrders(
        bytes32 orderbookId,
        bytes32[] calldata txHashes
    ) public view returns (
        (bytes32, Side, uint16, uint256, uint256, uint128, uint128, uint256, uint256)[] memory
    ) {}

    // --- Fund Management ---

    /**
     * @notice Deposits tokens into the exchange to be used for trading.
     * @param token The address of the token to deposit.
     * @param recipient The address that will be credited with the deposit.
     * @param amount The amount of tokens to deposit (in atomic units).
     * @param deadline The Unix timestamp after which the deposit is invalid in microseconds. Must be a multiple of the `auction_interval`.
     */
    function deposit(
        address token,
        address recipient,
        uint256 amount,
        uint128 deadline
    ) public {}

    /**
     * @notice Withdraws tokens from the exchange to an external wallet.
     * @param token The address of the ERC20 token to withdraw.
     * @param recipient The address receiving the withdrawn tokens.
     * @param amount The amount of tokens to withdraw.
     * @param deadline The Unix timestamp after which the withdrawal is invalid in microseconds. Must be a multiple of the `auction_interval`.
     */
    function withdraw(
        address token,
        address recipient,
        uint256 amount,
        uint128 deadline
    ) public {}

    // --- Batch envelope ---

    /**
     * @notice Carries multiple single-intent calls in one signed transaction.
     * @dev Each `inner[i]` is the full ABI-encoded calldata of one of the other
     *      single-intent functions on this contract — `submitOrder`, `cancel`,
     *      `update`, `submitTrigger`, `cancelTrigger`, `updateTrigger`,
     *      `deposit`, or `withdraw`. The whole envelope is atomic: it lands in a
     *      single auction tick, so every sub-intent must carry the **same**
     *      `deadline`. Constraints (enforced at validation):
     *      - 1 to 64 sub-intents (the cap is configurable by the operator).
     *      - All sub-intents share one `deadline` (uniform-deadline invariant).
     *      - Nested batches are rejected — `inner[i]` may not itself be a `submitBatch`.
     * @param inner The ABI-encoded calldata of each sub-intent, in order.
     */
    function submitBatch(bytes[] calldata inner) public {}
}

Last updated