Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Module 0x7::bulk_order_book

Bulk Order Book Module

This module implements a bulk order book system that allows traders to place orders with multiple price levels simultaneously. The bulk order book supports both maker and taker orders, with sophisticated order matching, cancellation, and reinsertion capabilities.

Key Features:

1. Multi-Level Orders

  • Traders can place orders with multiple price levels in a single transaction
  • Bid orders: Prices must be in descending order (best price first)
  • Ask orders: Prices must be in ascending order (best price first)
  • Each price level has an associated size

2. Order Matching

  • Price-time priority: Orders are matched based on price first, then time
  • Partial fills: Orders can be partially filled across multiple levels
  • Automatic level progression: When a price level is fully consumed, the next level becomes active

3. Order Management

  • Cancellation: Orders can be cancelled, clearing all active levels
  • Reinsertion: Matched portions of orders can be reinserted back into the order book
  • Order ID Reuse: Cancelled orders allow the same account to place new orders with the same ID

Data Structures:

  • BulkOrderBook: Main order book container
  • BulkOrderRequest: Request structure for placing new orders
  • BulkOrder: Internal representation of a multi-level order
  • BulkOrderResult: Result of order matching operations
  • SingleBulkOrderMatch: Single match result between orders

Error Codes:

use 0x1::big_ordered_map;
use 0x1::option;
use 0x5::bulk_order_types;
use 0x5::order_book_types;
use 0x5::order_match_types;
use 0x7::bulk_order_utils;
use 0x7::order_book_utils;
use 0x7::order_id_generation;
use 0x7::price_time_index;

Enum BulkOrderBook

Main bulk order book container that manages all orders and their matching.

Fields:

  • orders: Map of account addresses to their bulk orders
  • order_id_to_address: Map of order IDs to account addresses for lookup
enum BulkOrderBook<M: copy, drop, store> has store
Variants
V1
Fields
orders: big_ordered_map::BigOrderedMap<address, bulk_order_types::BulkOrder<M>>
order_id_to_address: big_ordered_map::BigOrderedMap<order_book_types::OrderId, address>

Constants

const E_REINSERT_ORDER_MISMATCH: u64 = 8;

const EPRICE_CROSSING: u64 = 11;

const E_INVALID_SEQUENCE_NUMBER: u64 = 13;

const EINVALID_ADD_SIZE_TO_ORDER: u64 = 6;

const EINVALID_INACTIVE_ORDER_STATE: u64 = 5;

const EINVLID_MM_ORDER_REQUEST: u64 = 10;

const ENOT_BULK_ORDER: u64 = 12;

const EORDER_ALREADY_EXISTS: u64 = 1;

const EORDER_CREATOR_MISMATCH: u64 = 9;

const EORDER_NOT_FOUND: u64 = 4;

const EPOST_ONLY_FILLED: u64 = 2;

const E_NOT_ACTIVE_ORDER: u64 = 7;

Function new_bulk_order_book

Creates a new empty bulk order book.

Returns:

A new BulkOrderBook instance with empty order collections.

public(friend) fun new_bulk_order_book<M: copy, drop, store>(): bulk_order_book::BulkOrderBook<M>
Implementation
public(friend) fun new_bulk_order_book<M: store + copy + drop>(): BulkOrderBook<M> {
    BulkOrderBook::V1 {
        orders: order_book_utils::new_default_big_ordered_map(),
        order_id_to_address: order_book_utils::new_default_big_ordered_map()
    }
}

Function get_single_match_for_taker

Returns a single match for a taker order.

This function should only be called after verifying that the order is a taker order using is_taker_order(). If called on a non-taker order, it will abort.

Arguments:

  • self: Mutable reference to the bulk order book
  • price_time_idx: Mutable reference to the price time index
  • price: The price of the taker order
  • size: The size of the taker order
  • is_bid: True if the taker order is a bid, false if ask

Returns:

A SingleBulkOrderMatch containing the match details.

Side Effects:

  • Updates the matched order’s remaining sizes
  • Activates the next price level if the current level is fully consumed
  • Updates the active order book
public(friend) fun get_single_match_for_taker<M: copy, drop, store>(self: &mut bulk_order_book::BulkOrderBook<M>, price_time_idx: &mut price_time_index::PriceTimeIndex, active_matched_order: order_match_types::ActiveMatchedOrder, is_bid: bool): order_match_types::OrderMatch<M>
Implementation
public(friend) fun get_single_match_for_taker<M: store + copy + drop>(
    self: &mut BulkOrderBook<M>,
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    active_matched_order: ActiveMatchedOrder,
    is_bid: bool
): OrderMatch<M> {
    let (order_id, matched_size, remaining_size, order_book_type) =
        active_matched_order.destroy_active_matched_order();
    assert!(order_book_type == bulk_order_type(), ENOT_BULK_ORDER);
    let order_address = self.order_id_to_address.get(&order_id).destroy_some();
    let order = self.orders.remove(&order_address);
    let order_match = new_bulk_order_match<M>(&order, !is_bid, matched_size);
    let (next_price, next_size) =
        bulk_order_utils::match_order_and_get_next_from_bulk_order(
            &mut order, !is_bid, matched_size
        );
    if (remaining_size == 0 && next_price.is_some()) {
        let price = next_price.destroy_some();
        let size = next_size.destroy_some();
        price_time_idx.place_maker_order(
            order_id,
            bulk_order_type(),
            price,
            order.get_unique_priority_idx(),
            size,
            !is_bid
        );
    };
    self.orders.add(order_address, order);
    return order_match
}

Function cancel_active_order_for_side

Cancels active orders for a specific side (bid or ask) of a bulk order.

Arguments:

  • active_orders: Reference to the active order book
  • order: The bulk order to cancel active orders for
  • is_bid: True to cancel bid orders, false for ask orders
fun cancel_active_order_for_side<M: copy, drop, store>(price_time_idx: &mut price_time_index::PriceTimeIndex, order: &bulk_order_types::BulkOrder<M>, is_bid: bool)
Implementation
fun cancel_active_order_for_side<M: store + copy + drop>(
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    order: &BulkOrder<M>,
    is_bid: bool
) {
    let active_price = order.get_order_request().get_active_price(is_bid);
    if (active_price.is_some()) {
        price_time_idx.cancel_active_order(
            active_price.destroy_some(),
            order.get_unique_priority_idx(),
            is_bid
        );
    };
}

Function cancel_active_orders

Cancels all active orders (both bid and ask) for a bulk order.

Arguments:

  • active_orders: Reference to the active order book
  • order: The bulk order to cancel active orders for
fun cancel_active_orders<M: copy, drop, store>(price_time_idx: &mut price_time_index::PriceTimeIndex, order: &bulk_order_types::BulkOrder<M>)
Implementation
fun cancel_active_orders<M: store + copy + drop>(
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    order: &BulkOrder<M>
) {
    cancel_active_order_for_side(price_time_idx, order, true); // cancel bid
    cancel_active_order_for_side(price_time_idx, order, false); // cancel ask
}

Function activate_first_price_level_for_side

Activates the first price level for a specific side of a bulk order.

Arguments:

  • active_orders: Reference to the active order book
  • order: The bulk order to activate levels for
  • order_id: The order ID for the bulk order
  • is_bid: True to activate bid levels, false for ask levels
fun activate_first_price_level_for_side<M: copy, drop, store>(price_time_idx: &mut price_time_index::PriceTimeIndex, order: &bulk_order_types::BulkOrder<M>, order_id: order_book_types::OrderId, is_bid: bool)
Implementation
fun activate_first_price_level_for_side<M: store + copy + drop>(
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    order: &BulkOrder<M>,
    order_id: OrderId,
    is_bid: bool
) {
    let order_request = order.get_order_request();
    let active_price = order_request.get_active_price(is_bid);
    let active_size = order_request.get_active_size(is_bid);
    if (active_price.is_some()) {
        price_time_idx.place_maker_order(
            order_id,
            bulk_order_type(),
            active_price.destroy_some(),
            order.get_unique_priority_idx(),
            active_size.destroy_some(),
            is_bid
        );
    }
}

Function activate_first_price_levels

Activates the first price levels for both bid and ask sides of a bulk order.

Arguments:

  • active_orders: Reference to the active order book
  • order: The bulk order to activate levels for
  • order_id: The order ID for the bulk order
fun activate_first_price_levels<M: copy, drop, store>(price_time_idx: &mut price_time_index::PriceTimeIndex, order: &bulk_order_types::BulkOrder<M>, order_id: order_book_types::OrderId)
Implementation
fun activate_first_price_levels<M: store + copy + drop>(
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    order: &BulkOrder<M>,
    order_id: OrderId
) {
    activate_first_price_level_for_side(price_time_idx, order, order_id, true); // activate bid
    activate_first_price_level_for_side(price_time_idx, order, order_id, false); // activate ask
}

Function reinsert_order

Reinserts a bulk order back into the order book after it has been matched.

This function allows traders to reinsert portions of their orders that were matched, effectively allowing them to “reuse” matched liquidity.

Arguments:

  • self: Mutable reference to the bulk order book
  • price_time_idx: Mutable reference to the price time index
  • reinsert_order: The order result to reinsert
  • original_order: The original order result for validation

Aborts:

  • If the order account doesn’t exist in the order book
  • If the reinsertion validation fails
public(friend) fun reinsert_order<M: copy, drop, store>(self: &mut bulk_order_book::BulkOrderBook<M>, price_time_idx: &mut price_time_index::PriceTimeIndex, reinsert_order: order_match_types::OrderMatchDetails<M>, original_order: &order_match_types::OrderMatchDetails<M>)
Implementation
public(friend) fun reinsert_order<M: store + copy + drop>(
    self: &mut BulkOrderBook<M>,
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    reinsert_order: OrderMatchDetails<M>,
    original_order: &OrderMatchDetails<M>
) {
    assert!(
        reinsert_order.validate_bulk_order_reinsertion_request(original_order),
        E_REINSERT_ORDER_MISMATCH
    );
    let account = reinsert_order.get_account_from_match_details();
    let order_option = self.orders.remove_or_none(&account);
    assert!(order_option.is_some(), EORDER_NOT_FOUND);
    let order = order_option.destroy_some();
    cancel_active_orders(price_time_idx, &order);
    bulk_order_utils::reinsert_order_into_bulk_order(&mut order, &reinsert_order);
    activate_first_price_levels(
        price_time_idx, &order, reinsert_order.get_order_id_from_match_details()
    );
    self.orders.add(account, order);
}

Function cancel_bulk_order

Cancels a bulk order for the specified account.

Instead of removing the order entirely, this function clears all active levels and sets the order to empty state, allowing the same account to place new orders with the same order ID in the future.

Arguments:

  • self: Mutable reference to the bulk order book
  • price_time_idx: Mutable reference to the price time index
  • account: The account whose order should be cancelled

Aborts:

  • If no order exists for the specified account
public(friend) fun cancel_bulk_order<M: copy, drop, store>(self: &mut bulk_order_book::BulkOrderBook<M>, price_time_idx: &mut price_time_index::PriceTimeIndex, account: address): bulk_order_types::BulkOrder<M>
Implementation
public(friend) fun cancel_bulk_order<M: store + copy + drop>(
    self: &mut BulkOrderBook<M>,
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    account: address
): BulkOrder<M> {
    // For cancellation, instead of removing the order, we will just cancel the active orders and set the sizes to 0.
    // This allows us to reuse the order id for the same account in the future without creating a new order.
    let order_opt = self.orders.remove_or_none(&account);
    assert!(order_opt.is_some(), EORDER_NOT_FOUND);
    let order = order_opt.destroy_some();
    let order_copy = order;
    cancel_active_orders(price_time_idx, &order);
    order.set_empty();
    self.orders.add(account, order);
    order_copy
}

Function cancel_bulk_order_at_price

Cancels a specific price level in a bulk order.

This function removes only the specified price level from the bulk order, keeping all other price levels intact. If the cancelled price level was active, it will be removed from the active order book and the next price level (if any) will be activated.

Arguments:

  • self: Mutable reference to the bulk order book
  • price_time_idx: Mutable reference to the price time index
  • account: The account whose order contains the price level to cancel
  • price: The price level to cancel
  • is_bid: True to cancel from bid side, false for ask side

Returns:

A tuple containing:

  • The cancelled size at that price level
  • The updated bulk order (copy for event emission)

Aborts:

  • If no order exists for the specified account
public(friend) fun cancel_bulk_order_at_price<M: copy, drop, store>(self: &mut bulk_order_book::BulkOrderBook<M>, price_time_idx: &mut price_time_index::PriceTimeIndex, account: address, price: u64, is_bid: bool): (u64, bulk_order_types::BulkOrder<M>)
Implementation
public(friend) fun cancel_bulk_order_at_price<M: store + copy + drop>(
    self: &mut BulkOrderBook<M>,
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    account: address,
    price: u64,
    is_bid: bool
): (u64, BulkOrder<M>) {
    let order_opt = self.orders.remove_or_none(&account);
    assert!(order_opt.is_some(), EORDER_NOT_FOUND);
    let order = order_opt.destroy_some();

    // Check if the price to cancel is the currently active price
    let active_price = order.get_order_request().get_active_price(is_bid);
    let was_active = active_price.is_some() && active_price.destroy_some() == price;

    // If this was the active price level, we need to cancel it from the active order book first
    if (was_active) {
        cancel_active_order_for_side(price_time_idx, &order, is_bid);
    };

    // Cancel the specific price level
    let cancelled_size =
        bulk_order_utils::cancel_at_price_level(&mut order, price, is_bid);

    // If this was the active price level, activate the next price level if available
    if (was_active) {
        let order_id = order.get_order_id();
        activate_first_price_level_for_side(price_time_idx, &order, order_id, is_bid);
    };

    let order_copy = order;
    self.orders.add(account, order);
    (cancelled_size, order_copy)
}

Function get_bulk_order

public(friend) fun get_bulk_order<M: copy, drop, store>(self: &bulk_order_book::BulkOrderBook<M>, account: address): bulk_order_types::BulkOrder<M>
Implementation
public(friend) fun get_bulk_order<M: store + copy + drop>(
    self: &BulkOrderBook<M>, account: address
): BulkOrder<M> {
    let result = self.orders.get(&account);
    assert!(result.is_some(), EORDER_NOT_FOUND);
    result.destroy_some()
}

Function get_remaining_size

public(friend) fun get_remaining_size<M: copy, drop, store>(self: &bulk_order_book::BulkOrderBook<M>, account: address, is_bid: bool): u64
Implementation
public(friend) fun get_remaining_size<M: store + copy + drop>(
    self: &BulkOrderBook<M>, account: address, is_bid: bool
): u64 {
    let result_option =
        self.orders.get_and_map(
            &account,
            |order| order.get_order_request().get_total_remaining_size(is_bid)
        );
    assert!(result_option.is_some(), EORDER_NOT_FOUND);
    result_option.destroy_some()
}

Function get_prices

public(friend) fun get_prices<M: copy, drop, store>(self: &bulk_order_book::BulkOrderBook<M>, account: address, is_bid: bool): vector<u64>
Implementation
public(friend) fun get_prices<M: store + copy + drop>(
    self: &BulkOrderBook<M>, account: address, is_bid: bool
): vector<u64> {
    let result_option =
        self.orders.get_and_map(
            &account,
            |order| order.get_order_request().get_all_prices(is_bid)
        );
    assert!(result_option.is_some(), EORDER_NOT_FOUND);
    result_option.destroy_some()
}

Function get_sizes

public(friend) fun get_sizes<M: copy, drop, store>(self: &bulk_order_book::BulkOrderBook<M>, account: address, is_bid: bool): vector<u64>
Implementation
public(friend) fun get_sizes<M: store + copy + drop>(
    self: &BulkOrderBook<M>, account: address, is_bid: bool
): vector<u64> {
    let result_option =
        self.orders.get_and_map(
            &account,
            |order| order.get_order_request().get_all_sizes(is_bid)
        );
    assert!(result_option.is_some(), EORDER_NOT_FOUND);
    result_option.destroy_some()
}

Function place_bulk_order

Places a new maker order in the bulk order book.

If an order already exists for the account, it will be replaced with the new order. The first price levels of both bid and ask sides will be activated in the active order book.

Arguments:

  • self: Mutable reference to the bulk order book
  • price_time_idx: Mutable reference to the price time index
  • order_req: The bulk order request to place

Aborts:

  • If the order request validation fails
public(friend) fun place_bulk_order<M: copy, drop, store>(self: &mut bulk_order_book::BulkOrderBook<M>, price_time_idx: &mut price_time_index::PriceTimeIndex, order_req: bulk_order_types::BulkOrderRequest<M>): bulk_order_types::BulkOrderPlaceResponse<M>
Implementation
public(friend) fun place_bulk_order<M: store + copy + drop>(
    self: &mut BulkOrderBook<M>,
    price_time_idx: &mut aptos_experimental::price_time_index::PriceTimeIndex,
    order_req: BulkOrderRequest<M>
): BulkOrderPlaceResponse<M> {
    let account = order_req.get_account();
    let new_sequence_number = order_req.get_sequence_number();
    let order_option = self.orders.remove_or_none(&account);
    let (order_id, previous_seq_num) =
        if (order_option.is_some()) {
            let old_order = order_option.destroy_some();
            let existing_sequence_number =
                old_order.get_order_request().get_sequence_number();
            // Return rejection response instead of aborting
            if (new_sequence_number <= existing_sequence_number) {
                // Put the old order back
                self.orders.add(account, old_order);
                return new_bulk_order_place_response_rejection(
                    account,
                    new_sequence_number,
                    existing_sequence_number
                )
            };
            cancel_active_orders(price_time_idx, &old_order);
            (old_order.get_order_id(), std::option::some(existing_sequence_number))
        } else {
            let order_id = next_order_id();
            self.order_id_to_address.add(order_id, account);
            (order_id, std::option::none())
        };
    let (
        bulk_order,
        cancelled_bid_prices,
        cancelled_bid_sizes,
        cancelled_ask_prices,
        cancelled_ask_sizes
    ) =
        bulk_order_utils::new_bulk_order_with_sanitization(
            order_id,
            next_increasing_idx_type(),
            order_req,
            price_time_idx.best_bid_price(),
            price_time_idx.best_ask_price()
        );
    self.orders.add(account, bulk_order);
    // Activate the first price levels in the active order book
    activate_first_price_levels(price_time_idx, &bulk_order, order_id);
    new_bulk_order_place_response_success(
        bulk_order,
        cancelled_bid_prices,
        cancelled_bid_sizes,
        cancelled_ask_prices,
        cancelled_ask_sizes,
        previous_seq_num
    )
}