Skip to main content

Module deepbook::clob

use deepbook::critbit;
use deepbook::custodian;
use deepbook::math;
use std::address;
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::type_name;
use std::vector;
use sui::address;
use sui::bag;
use sui::balance;
use sui::clock;
use sui::coin;
use sui::config;
use sui::deny_list;
use sui::dynamic_field;
use sui::dynamic_object_field;
use sui::event;
use sui::hex;
use sui::linked_table;
use sui::object;
use sui::sui;
use sui::table;
use sui::transfer;
use sui::tx_context;
use sui::types;
use sui::url;
use sui::vec_set;

Struct PoolCreated

Emitted when a new pool is created

public struct PoolCreated has copy, drop, store
Click to open
Fields
pool_id: sui::object::ID
object ID of the newly created pool
base_asset: std::type_name::TypeName
quote_asset: std::type_name::TypeName
taker_fee_rate: u64
maker_rebate_rate: u64
tick_size: u64
lot_size: u64

Struct OrderPlacedV2

Emitted when a maker order is injected into the order book.

public struct OrderPlacedV2<phantom BaseAsset, phantom QuoteAsset> has copy, drop, store
Click to open
Fields
pool_id: sui::object::ID
object ID of the pool the order was placed on
order_id: u64
ID of the order within the pool
is_bid: bool
owner: sui::object::ID
object ID of the AccountCap that placed the order
base_asset_quantity_placed: u64
price: u64
expire_timestamp: u64

Struct OrderCanceled

Emitted when a maker order is canceled.

public struct OrderCanceled<phantom BaseAsset, phantom QuoteAsset> has copy, drop, store
Click to open
Fields
pool_id: sui::object::ID
object ID of the pool the order was placed on
order_id: u64
ID of the order within the pool
is_bid: bool
owner: sui::object::ID
object ID of the AccountCap that placed the order
base_asset_quantity_canceled: u64
price: u64

Struct OrderFilledV2

Emitted only when a maker order is filled.

public struct OrderFilledV2<phantom BaseAsset, phantom QuoteAsset> has copy, drop, store
Click to open
Fields
pool_id: sui::object::ID
object ID of the pool the order was placed on
order_id: u64
ID of the order within the pool
is_bid: bool
owner: sui::object::ID
object ID of the AccountCap that placed the order
total_quantity: u64
base_asset_quantity_filled: u64
base_asset_quantity_remaining: u64
price: u64
taker_commission: u64
maker_rebates: u64

Struct Order

public struct Order has drop, store
Click to open
Fields
order_id: u64
price: u64
quantity: u64
is_bid: bool
owner: sui::object::ID
expire_timestamp: u64

Struct TickLevel

public struct TickLevel has store
Click to open
Fields

Struct Pool

public struct Pool<phantom BaseAsset, phantom QuoteAsset> has key
Click to open
Fields
id: sui::object::UID
bids: deepbook::critbit::CritbitTree<deepbook::clob::TickLevel>
asks: deepbook::critbit::CritbitTree<deepbook::clob::TickLevel>
next_bid_order_id: u64
next_ask_order_id: u64
usr_open_orders: sui::table::Table<sui::object::ID, sui::linked_table::LinkedTable<u64, u64>>
taker_fee_rate: u64
maker_rebate_rate: u64
tick_size: u64
lot_size: u64
base_custodian: deepbook::custodian::Custodian<BaseAsset>
quote_custodian: deepbook::custodian::Custodian<QuoteAsset>
creation_fee: sui::balance::Balance<sui::sui::SUI>
base_asset_trading_fees: sui::balance::Balance<BaseAsset>
quote_asset_trading_fees: sui::balance::Balance<QuoteAsset>

Struct OrderPlaced

Deprecated since v1.0.0, use OrderPlacedV2 instead.

public struct OrderPlaced<phantom BaseAsset, phantom QuoteAsset> has copy, drop, store
Click to open
Fields
pool_id: sui::object::ID
object ID of the pool the order was placed on
order_id: u64
ID of the order within the pool
is_bid: bool
owner: sui::object::ID
object ID of the AccountCap that placed the order
base_asset_quantity_placed: u64
price: u64

Struct OrderFilled

Deprecated since v1.0.0, use OrderFilledV2 instead.

public struct OrderFilled<phantom BaseAsset, phantom QuoteAsset> has copy, drop, store
Click to open
Fields
pool_id: sui::object::ID
object ID of the pool the order was placed on
order_id: u64
ID of the order within the pool
is_bid: bool
owner: sui::object::ID
object ID of the AccountCap that placed the order
total_quantity: u64
base_asset_quantity_filled: u64
base_asset_quantity_remaining: u64
price: u64

Constants

const DEPRECATED: u64 = 0;

const EInvalidOrderId: u64 = 3;

const EInvalidQuantity: u64 = 6;

const EInvalidTickPrice: u64 = 11;

const EInvalidUser: u64 = 12;

const EUnauthorizedCancel: u64 = 4;

const MIN_ASK_ORDER_ID: u64 = 9223372036854775808;

Function destroy_empty_level

fun destroy_empty_level(level: deepbook::clob::TickLevel)
Click to open
Implementation
fun destroy_empty_level(level: TickLevel) {
    let TickLevel {
        price: _,
        open_orders: orders,
    } = level;
    linked_table::destroy_empty(orders);
}

Function create_account

public fun create_account(_ctx: &mut sui::tx_context::TxContext): deepbook::custodian::AccountCap
Click to open
Implementation
public fun create_account(_ctx: &mut TxContext): AccountCap {
    abort DEPRECATED
}

Function create_pool

public fun create_pool<BaseAsset, QuoteAsset>(_tick_size: u64, _lot_size: u64, _creation_fee: sui::coin::Coin<sui::sui::SUI>, _ctx: &mut sui::tx_context::TxContext)
Click to open
Implementation
public fun create_pool<BaseAsset, QuoteAsset>(
    _tick_size: u64,
    _lot_size: u64,
    _creation_fee: Coin<SUI>,
    _ctx: &mut TxContext,
) {
    abort DEPRECATED
}

Function deposit_base

public fun deposit_base<BaseAsset, QuoteAsset>(_pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, _coin: sui::coin::Coin<BaseAsset>, _account_cap: &deepbook::custodian::AccountCap)
Click to open
Implementation
public fun deposit_base<BaseAsset, QuoteAsset>(
    _pool: &mut Pool<BaseAsset, QuoteAsset>,
    _coin: Coin<BaseAsset>,
    _account_cap: &AccountCap
) {
    abort 1337
}

Function deposit_quote

public fun deposit_quote<BaseAsset, QuoteAsset>(_pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, _coin: sui::coin::Coin<QuoteAsset>, _account_cap: &deepbook::custodian::AccountCap)
Click to open
Implementation
public fun deposit_quote<BaseAsset, QuoteAsset>(
    _pool: &mut Pool<BaseAsset, QuoteAsset>,
    _coin: Coin<QuoteAsset>,
    _account_cap: &AccountCap
) {
    abort 1337
}

Function withdraw_base

public fun withdraw_base<BaseAsset, QuoteAsset>(pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, quantity: u64, account_cap: &deepbook::custodian::AccountCap, ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<BaseAsset>
Click to open
Implementation
public fun withdraw_base<BaseAsset, QuoteAsset>(
    pool: &mut Pool<BaseAsset, QuoteAsset>,
    quantity: u64,
    account_cap: &AccountCap,
    ctx: &mut TxContext
): Coin<BaseAsset> {
    assert!(quantity > 0, EInvalidQuantity);
    custodian::withdraw_asset(&mut pool.base_custodian, quantity, account_cap, ctx)
}

Function withdraw_quote

public fun withdraw_quote<BaseAsset, QuoteAsset>(pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, quantity: u64, account_cap: &deepbook::custodian::AccountCap, ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<QuoteAsset>
Click to open
Implementation
public fun withdraw_quote<BaseAsset, QuoteAsset>(
    pool: &mut Pool<BaseAsset, QuoteAsset>,
    quantity: u64,
    account_cap: &AccountCap,
    ctx: &mut TxContext
): Coin<QuoteAsset> {
    assert!(quantity > 0, EInvalidQuantity);
    custodian::withdraw_asset(&mut pool.quote_custodian, quantity, account_cap, ctx)
}

Function swap_exact_base_for_quote

public fun swap_exact_base_for_quote<BaseAsset, QuoteAsset>(_pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, _quantity: u64, _base_coin: sui::coin::Coin<BaseAsset>, _quote_coin: sui::coin::Coin<QuoteAsset>, _clock: &sui::clock::Clock, _ctx: &mut sui::tx_context::TxContext): (sui::coin::Coin<BaseAsset>, sui::coin::Coin<QuoteAsset>, u64)
Click to open
Implementation
public fun swap_exact_base_for_quote<BaseAsset, QuoteAsset>(
    _pool: &mut Pool<BaseAsset, QuoteAsset>,
    _quantity: u64,
    _base_coin: Coin<BaseAsset>,
    _quote_coin: Coin<QuoteAsset>,
    _clock: &Clock,
    _ctx: &mut TxContext,
): (Coin<BaseAsset>, Coin<QuoteAsset>, u64) {
    abort 1337
}

Function swap_exact_quote_for_base

public fun swap_exact_quote_for_base<BaseAsset, QuoteAsset>(_pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, _quantity: u64, _clock: &sui::clock::Clock, _quote_coin: sui::coin::Coin<QuoteAsset>, _ctx: &mut sui::tx_context::TxContext): (sui::coin::Coin<BaseAsset>, sui::coin::Coin<QuoteAsset>, u64)
Click to open
Implementation
public fun swap_exact_quote_for_base<BaseAsset, QuoteAsset>(
    _pool: &mut Pool<BaseAsset, QuoteAsset>,
    _quantity: u64,
    _clock: &Clock,
    _quote_coin: Coin<QuoteAsset>,
    _ctx: &mut TxContext,
): (Coin<BaseAsset>, Coin<QuoteAsset>, u64) {
    abort 1337
}

Function place_market_order

Place a market order to the order book.

public fun place_market_order<BaseAsset, QuoteAsset>(_pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, _quantity: u64, _is_bid: bool, _base_coin: sui::coin::Coin<BaseAsset>, _quote_coin: sui::coin::Coin<QuoteAsset>, _clock: &sui::clock::Clock, _ctx: &mut sui::tx_context::TxContext): (sui::coin::Coin<BaseAsset>, sui::coin::Coin<QuoteAsset>)
Click to open
Implementation
public fun place_market_order<BaseAsset, QuoteAsset>(
    _pool: &mut Pool<BaseAsset, QuoteAsset>,
    _quantity: u64,
    _is_bid: bool,
    mut _base_coin: Coin<BaseAsset>,
    mut _quote_coin: Coin<QuoteAsset>,
    _clock: &Clock,
    _ctx: &mut TxContext,
): (Coin<BaseAsset>, Coin<QuoteAsset>) {
    abort 1337
}

Function place_limit_order

Place a limit order to the order book. Returns (base quantity filled, quote quantity filled, whether a maker order is being placed, order id of the maker order). When the limit order is not successfully placed, we return false to indicate that and also returns a meaningless order_id 0. When the limit order is successfully placed, we return true to indicate that and also the corresponding order_id. So please check that boolean value first before using the order id.

public fun place_limit_order<BaseAsset, QuoteAsset>(_pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, _price: u64, _quantity: u64, _is_bid: bool, _expire_timestamp: u64, _restriction: u8, _clock: &sui::clock::Clock, _account_cap: &deepbook::custodian::AccountCap, _ctx: &mut sui::tx_context::TxContext): (u64, u64, bool, u64)
Click to open
Implementation
public fun place_limit_order<BaseAsset, QuoteAsset>(
    _pool: &mut Pool<BaseAsset, QuoteAsset>,
    _price: u64,
    _quantity: u64,
    _is_bid: bool,
    _expire_timestamp: u64, // Expiration timestamp in ms in absolute value inclusive.
    _restriction: u8,
    _clock: &Clock,
    _account_cap: &AccountCap,
    _ctx: &mut TxContext
): (u64, u64, bool, u64) {
   abort 1337
}

Function order_is_bid

fun order_is_bid(order_id: u64): bool
Click to open
Implementation
fun order_is_bid(order_id: u64): bool {
    return order_id < MIN_ASK_ORDER_ID
}

Function emit_order_canceled

fun emit_order_canceled<BaseAsset, QuoteAsset>(pool_id: sui::object::ID, order: &deepbook::clob::Order)
Click to open
Implementation
fun emit_order_canceled<BaseAsset, QuoteAsset>(
    pool_id: ID,
    order: &Order
) {
    event::emit(OrderCanceled<BaseAsset, QuoteAsset> {
        pool_id,
        order_id: order.order_id,
        is_bid: order.is_bid,
        owner: order.owner,
        base_asset_quantity_canceled: order.quantity,
        price: order.price
    })
}

Function cancel_order

Cancel and opening order. Abort if order_id is invalid or if the order is not submitted by the transaction sender.

public fun cancel_order<BaseAsset, QuoteAsset>(pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, order_id: u64, account_cap: &deepbook::custodian::AccountCap)
Click to open
Implementation
public fun cancel_order<BaseAsset, QuoteAsset>(
    pool: &mut Pool<BaseAsset, QuoteAsset>,
    order_id: u64,
    account_cap: &AccountCap
) {
    // First check the highest bit of the order id to see whether it's bid or ask.
    // Then retrieve the price using the order id.
    // Using the price to retrieve the corresponding PriceLevel from the bids / asks Critbit Tree.
    // Retrieve and remove the order from open orders of the PriceLevel.
    let user = object::id(account_cap);
    assert!(contains(&pool.usr_open_orders, user), EInvalidUser);
    let usr_open_orders = borrow_mut(&mut pool.usr_open_orders, user);
    assert!(linked_table::contains(usr_open_orders, order_id), EInvalidOrderId);
    let tick_price = *linked_table::borrow(usr_open_orders, order_id);
    let is_bid = order_is_bid(order_id);
    let (tick_exists, tick_index) = find_leaf(
        if (is_bid) { &pool.bids } else { &pool.asks },
        tick_price);
    assert!(tick_exists, EInvalidOrderId);
    let order = remove_order(
        if (is_bid) { &mut pool.bids } else { &mut pool.asks },
        usr_open_orders,
        tick_index,
        order_id,
        user
    );
    if (is_bid) {
        let balance_locked = clob_math::mul(order.quantity, order.price);
        custodian::unlock_balance(&mut pool.quote_custodian, user, balance_locked);
    } else {
        custodian::unlock_balance(&mut pool.base_custodian, user, order.quantity);
    };
    emit_order_canceled<BaseAsset, QuoteAsset>(*object::uid_as_inner(&pool.id), &order);
}

Function remove_order

fun remove_order(open_orders: &mut deepbook::critbit::CritbitTree<deepbook::clob::TickLevel>, usr_open_orders: &mut sui::linked_table::LinkedTable<u64, u64>, tick_index: u64, order_id: u64, user: sui::object::ID): deepbook::clob::Order
Click to open
Implementation
fun remove_order(
    open_orders: &mut CritbitTree<TickLevel>,
    usr_open_orders: &mut LinkedTable<u64, u64>,
    tick_index: u64,
    order_id: u64,
    user: ID,
): Order {
    linked_table::remove(usr_open_orders, order_id);
    let tick_level = borrow_leaf_by_index(open_orders, tick_index);
    assert!(linked_table::contains(&tick_level.open_orders, order_id), EInvalidOrderId);
    let mut_tick_level = borrow_mut_leaf_by_index(open_orders, tick_index);
    let order = linked_table::remove(&mut mut_tick_level.open_orders, order_id);
    assert!(order.owner == user, EUnauthorizedCancel);
    if (linked_table::is_empty(&mut_tick_level.open_orders)) {
        destroy_empty_level(remove_leaf_by_index(open_orders, tick_index));
    };
    order
}

Function cancel_all_orders

public fun cancel_all_orders<BaseAsset, QuoteAsset>(pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, account_cap: &deepbook::custodian::AccountCap)
Click to open
Implementation
public fun cancel_all_orders<BaseAsset, QuoteAsset>(
    pool: &mut Pool<BaseAsset, QuoteAsset>,
    account_cap: &AccountCap
) {
    let pool_id = *object::uid_as_inner(&pool.id);
    let user = object::id(account_cap);
    assert!(contains(&pool.usr_open_orders, user), EInvalidUser);
    let usr_open_order_ids = table::borrow_mut(&mut pool.usr_open_orders, user);
    while (!linked_table::is_empty(usr_open_order_ids)) {
        let order_id = *option::borrow(linked_table::back(usr_open_order_ids));
        let order_price = *linked_table::borrow(usr_open_order_ids, order_id);
        let is_bid = order_is_bid(order_id);
        let open_orders =
            if (is_bid) { &mut pool.bids }
            else { &mut pool.asks };
        let (_, tick_index) = critbit::find_leaf(open_orders, order_price);
        let order = remove_order(
            open_orders,
            usr_open_order_ids,
            tick_index,
            order_id,
            user
        );
        if (is_bid) {
            let balance_locked = clob_math::mul(order.quantity, order.price);
            custodian::unlock_balance(&mut pool.quote_custodian, user, balance_locked);
        } else {
            custodian::unlock_balance(&mut pool.base_custodian, user, order.quantity);
        };
        emit_order_canceled<BaseAsset, QuoteAsset>(pool_id, &order);
    };
}

Function batch_cancel_order

Batch cancel limit orders to save gas cost. Abort if any of the order_ids are not submitted by the sender. Skip any order_id that is invalid. Note that this function can reduce gas cost even further if caller has multiple orders at the same price level, and if orders with the same price are grouped together in the vector. For example, if we have the following order_id to price mapping, {0: 100., 1: 200., 2: 100., 3: 200.}. Grouping order_ids like [0, 2, 1, 3] would make it the most gas efficient.

public fun batch_cancel_order<BaseAsset, QuoteAsset>(pool: &mut deepbook::clob::Pool<BaseAsset, QuoteAsset>, order_ids: vector<u64>, account_cap: &deepbook::custodian::AccountCap)
Click to open
Implementation
public fun batch_cancel_order<BaseAsset, QuoteAsset>(
    pool: &mut Pool<BaseAsset, QuoteAsset>,
    order_ids: vector<u64>,
    account_cap: &AccountCap
) {
    let pool_id = *object::uid_as_inner(&pool.id);
    // First group the order ids according to price level,
    // so that we don't have to retrieve the PriceLevel multiple times if there are orders at the same price level.
    // Iterate over each price level, retrieve the corresponding PriceLevel.
    // Iterate over the order ids that need to be canceled at that price level,
    // retrieve and remove the order from open orders of the PriceLevel.
    let user = object::id(account_cap);
    assert!(contains(&pool.usr_open_orders, user), 0);
    let mut tick_index: u64 = 0;
    let mut tick_price: u64 = 0;
    let n_order = vector::length(&order_ids);
    let mut i_order = 0;
    let usr_open_orders = borrow_mut(&mut pool.usr_open_orders, user);
    while (i_order < n_order) {
        let order_id = *vector::borrow(&order_ids, i_order);
        assert!(linked_table::contains(usr_open_orders, order_id), EInvalidOrderId);
        let new_tick_price = *linked_table::borrow(usr_open_orders, order_id);
        let is_bid = order_is_bid(order_id);
        if (new_tick_price != tick_price) {
            tick_price = new_tick_price;
            let (tick_exists, new_tick_index) = find_leaf(
                if (is_bid) { &pool.bids } else { &pool.asks },
                tick_price
            );
            assert!(tick_exists, EInvalidTickPrice);
            tick_index = new_tick_index;
        };
        let order = remove_order(
            if (is_bid) { &mut pool.bids } else { &mut pool.asks },
            usr_open_orders,
            tick_index,
            order_id,
            user
        );
        if (is_bid) {
            let balance_locked = clob_math::mul(order.quantity, order.price);
            custodian::unlock_balance(&mut pool.quote_custodian, user, balance_locked);
        } else {
            custodian::unlock_balance(&mut pool.base_custodian, user, order.quantity);
        };
        emit_order_canceled<BaseAsset, QuoteAsset>(pool_id, &order);
        i_order = i_order + 1;
    }
}

Function list_open_orders

public fun list_open_orders<BaseAsset, QuoteAsset>(pool: &deepbook::clob::Pool<BaseAsset, QuoteAsset>, account_cap: &deepbook::custodian::AccountCap): vector<deepbook::clob::Order>
Click to open
Implementation
public fun list_open_orders<BaseAsset, QuoteAsset>(
    pool: &Pool<BaseAsset, QuoteAsset>,
    account_cap: &AccountCap
): vector<Order> {
    let user = object::id(account_cap);
    let usr_open_order_ids = table::borrow(&pool.usr_open_orders, user);
    let mut open_orders = vector::empty<Order>();
    let mut order_id = linked_table::front(usr_open_order_ids);
    while (!option::is_none(order_id)) {
        let order_price = *linked_table::borrow(usr_open_order_ids, *option::borrow(order_id));
        let tick_level =
            if (order_is_bid(*option::borrow(order_id))) borrow_leaf_by_key(&pool.bids, order_price)
            else borrow_leaf_by_key(&pool.asks, order_price);
        let order = linked_table::borrow(&tick_level.open_orders, *option::borrow(order_id));
        vector::push_back(&mut open_orders, Order {
            order_id: order.order_id,
            price: order.price,
            quantity: order.quantity,
            is_bid: order.is_bid,
            owner: order.owner,
            expire_timestamp: order.expire_timestamp
        });
        order_id = linked_table::next(usr_open_order_ids, *option::borrow(order_id));
    };
    open_orders
}

Function account_balance

query user balance inside custodian

public fun account_balance<BaseAsset, QuoteAsset>(pool: &deepbook::clob::Pool<BaseAsset, QuoteAsset>, account_cap: &deepbook::custodian::AccountCap): (u64, u64, u64, u64)
Click to open
Implementation
public fun account_balance<BaseAsset, QuoteAsset>(
    pool: &Pool<BaseAsset, QuoteAsset>,
    account_cap: &AccountCap
): (u64, u64, u64, u64) {
    let user = object::id(account_cap);
    let (base_avail, base_locked) = custodian::account_balance(&pool.base_custodian, user);
    let (quote_avail, quote_locked) = custodian::account_balance(&pool.quote_custodian, user);
    (base_avail, base_locked, quote_avail, quote_locked)
}

Function get_market_price

Query the market price of order book returns (best_bid_price, best_ask_price)

public fun get_market_price<BaseAsset, QuoteAsset>(pool: &deepbook::clob::Pool<BaseAsset, QuoteAsset>): (u64, u64)
Click to open
Implementation
public fun get_market_price<BaseAsset, QuoteAsset>(
    pool: &Pool<BaseAsset, QuoteAsset>
): (u64, u64){
    let (bid_price, _) = critbit::max_leaf(&pool.bids);
    let (ask_price, _) = critbit::min_leaf(&pool.asks);
    return (bid_price, ask_price)
}

Function get_level2_book_status_bid_side

Enter a price range and return the level2 order depth of all valid prices within this price range in bid side returns two vectors of u64 The previous is a list of all valid prices The latter is the corresponding depth list

public fun get_level2_book_status_bid_side<BaseAsset, QuoteAsset>(pool: &deepbook::clob::Pool<BaseAsset, QuoteAsset>, price_low: u64, price_high: u64, clock: &sui::clock::Clock): (vector<u64>, vector<u64>)
Click to open
Implementation
public fun get_level2_book_status_bid_side<BaseAsset, QuoteAsset>(
    pool: &Pool<BaseAsset, QuoteAsset>,
    mut price_low: u64,
    mut price_high: u64,
    clock: &Clock
): (vector<u64>, vector<u64>) {
    let (price_low_, _) = critbit::min_leaf(&pool.bids);
    if (price_low < price_low_) price_low = price_low_;
    let (price_high_, _) = critbit::max_leaf(&pool.bids);
    if (price_high > price_high_) price_high = price_high_;
    price_low = critbit::find_closest_key(&pool.bids, price_low);
    price_high = critbit::find_closest_key(&pool.bids, price_high);
    let mut price_vec = vector::empty<u64>();
    let mut depth_vec = vector::empty<u64>();
    if (price_low == 0) { return (price_vec, depth_vec) };
    while (price_low <= price_high) {
        let depth = get_level2_book_status(
            &pool.bids,
            price_low,
            clock::timestamp_ms(clock)
        );
        vector::push_back(&mut price_vec, price_low);
        vector::push_back(&mut depth_vec, depth);
        let (next_price, _) = critbit::next_leaf(&pool.bids, price_low);
        if (next_price == 0) { break }
        else { price_low = next_price };
    };
    (price_vec, depth_vec)
}

Function get_level2_book_status_ask_side

Enter a price range and return the level2 order depth of all valid prices within this price range in ask side returns two vectors of u64 The previous is a list of all valid prices The latter is the corresponding depth list

public fun get_level2_book_status_ask_side<BaseAsset, QuoteAsset>(pool: &deepbook::clob::Pool<BaseAsset, QuoteAsset>, price_low: u64, price_high: u64, clock: &sui::clock::Clock): (vector<u64>, vector<u64>)
Click to open
Implementation
public fun get_level2_book_status_ask_side<BaseAsset, QuoteAsset>(
    pool: &Pool<BaseAsset, QuoteAsset>,
    mut price_low: u64,
    mut price_high: u64,
    clock: &Clock
): (vector<u64>, vector<u64>) {
    let (price_low_, _) = critbit::min_leaf(&pool.asks);
    if (price_low < price_low_) price_low = price_low_;
    let (price_high_, _) = critbit::max_leaf(&pool.asks);
    if (price_high > price_high_) price_high = price_high_;
    price_low = critbit::find_closest_key(&pool.asks, price_low);
    price_high = critbit::find_closest_key(&pool.asks, price_high);
    let mut price_vec = vector::empty<u64>();
    let mut depth_vec = vector::empty<u64>();
    if (price_low == 0) { return (price_vec, depth_vec) };
    while (price_low <= price_high) {
        let depth = get_level2_book_status(
            &pool.asks,
            price_low,
            clock::timestamp_ms(clock)
        );
        vector::push_back(&mut price_vec, price_low);
        vector::push_back(&mut depth_vec, depth);
        let (next_price, _) = critbit::next_leaf(&pool.asks, price_low);
        if (next_price == 0) { break }
        else { price_low = next_price };
    };
    (price_vec, depth_vec)
}

Function get_level2_book_status

internal func to retrieve single depth of a tick price

fun get_level2_book_status(open_orders: &deepbook::critbit::CritbitTree<deepbook::clob::TickLevel>, price: u64, time_stamp: u64): u64
Click to open
Implementation
fun get_level2_book_status(
    open_orders: &CritbitTree<TickLevel>,
    price: u64,
    time_stamp: u64
): u64 {
    let tick_level = critbit::borrow_leaf_by_key(open_orders, price);
    let tick_open_orders = &tick_level.open_orders;
    let mut depth = 0;
    let mut order_id = linked_table::front(tick_open_orders);
    let mut order: &Order;
    while (!option::is_none(order_id)) {
        order = linked_table::borrow(tick_open_orders, *option::borrow(order_id));
        if (order.expire_timestamp > time_stamp) depth = depth + order.quantity;
        order_id = linked_table::next(tick_open_orders, *option::borrow(order_id));
    };
    depth
}

Function get_order_status

public fun get_order_status<BaseAsset, QuoteAsset>(pool: &deepbook::clob::Pool<BaseAsset, QuoteAsset>, order_id: u64, account_cap: &deepbook::custodian::AccountCap): &deepbook::clob::Order
Click to open
Implementation
public fun get_order_status<BaseAsset, QuoteAsset>(
    pool: &Pool<BaseAsset, QuoteAsset>,
    order_id: u64,
    account_cap: &AccountCap
): &Order {
    let user = object::id(account_cap);
    assert!(table::contains(&pool.usr_open_orders, user), EInvalidUser);
    let usr_open_order_ids = table::borrow(&pool.usr_open_orders, user);
    assert!(linked_table::contains(usr_open_order_ids, order_id), EInvalidOrderId);
    let order_price = *linked_table::borrow(usr_open_order_ids, order_id);
    let open_orders =
        if (order_id < MIN_ASK_ORDER_ID) { &pool.bids }
        else { &pool.asks };
    let tick_level = critbit::borrow_leaf_by_key(open_orders, order_price);
    let tick_open_orders = &tick_level.open_orders;
    let order = linked_table::borrow(tick_open_orders, order_id);
    order
}