From 4cabdea72910fa69bf335a8d2f5f712bb6f68d9a Mon Sep 17 00:00:00 2001 From: Connor Barr Date: Wed, 13 Mar 2024 17:19:22 +0000 Subject: [PATCH 1/2] Tick state struct --- contracts/sumtree-orderbook/src/order.rs | 17 ++++----- contracts/sumtree-orderbook/src/state.rs | 25 ++----------- .../sumtree-orderbook/src/tests/test_state.rs | 8 ++--- contracts/sumtree-orderbook/src/types/mod.rs | 2 ++ contracts/sumtree-orderbook/src/types/tick.rs | 36 +++++++++++++++++++ 5 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 contracts/sumtree-orderbook/src/types/tick.rs diff --git a/contracts/sumtree-orderbook/src/order.rs b/contracts/sumtree-orderbook/src/order.rs index 0ffb370..d0e020e 100644 --- a/contracts/sumtree-orderbook/src/order.rs +++ b/contracts/sumtree-orderbook/src/order.rs @@ -1,6 +1,6 @@ use crate::constants::{MAX_TICK, MIN_TICK}; use crate::error::ContractError; -use crate::state::{new_order_id, orders, ORDERBOOKS, TICK_LIQUIDITY}; +use crate::state::{new_order_id, orders, ORDERBOOKS}; use crate::types::{LimitOrder, OrderDirection}; use cosmwasm_std::{ensure, ensure_eq, DepsMut, Env, MessageInfo, Response, Uint128}; use cw_utils::{must_pay, nonpayable}; @@ -76,17 +76,14 @@ pub fn place_limit( if limit_order.quantity > Uint128::zero() { // Save the order to the orderbook orders().save(deps.storage, &(book_id, tick_id, order_id), &limit_order)?; - - // Update tick liquidity - TICK_LIQUIDITY.update(deps.storage, &(book_id, tick_id), |liquidity| { - Ok::( - liquidity - .unwrap_or_default() - .checked_add(limit_order.quantity)?, - ) - })?; } + // TODO: Update Tick State + // Update tick liquidity + // TICK_STATE.update(deps.storage, &(book_id, tick_id), |state| { + // let curr_state = state.unwrap_or_default(); + // })?; + Ok(response .add_attribute("method", "placeLimit") .add_attribute("owner", info.sender.to_string()) diff --git a/contracts/sumtree-orderbook/src/state.rs b/contracts/sumtree-orderbook/src/state.rs index 6f6972c..a4c75da 100644 --- a/contracts/sumtree-orderbook/src/state.rs +++ b/contracts/sumtree-orderbook/src/state.rs @@ -1,6 +1,6 @@ -use crate::types::{FilterOwnerOrders, LimitOrder, Orderbook}; +use crate::types::{FilterOwnerOrders, LimitOrder, Orderbook, TickState}; use crate::ContractError; -use cosmwasm_std::{Addr, Order, StdResult, Storage, Uint128}; +use cosmwasm_std::{Addr, Order, StdResult, Storage}; use cw_storage_plus::{Bound, Index, IndexList, IndexedMap, Item, Map, MultiIndex}; // Counters for ID tracking @@ -13,7 +13,7 @@ const DEFAULT_PAGE_SIZE: u8 = 50; pub const ORDERBOOKS: Map<&u64, Orderbook> = Map::new("orderbooks"); /// Key: (orderbook_id, tick) -pub const TICK_LIQUIDITY: Map<&(u64, i64), Uint128> = Map::new("tick_liquidity"); +pub const TICK_STATE: Map<&(u64, i64), TickState> = Map::new("tick_state"); pub struct OrderIndexes { // Index by owner; Generic types: MultiIndex @@ -68,25 +68,6 @@ pub fn new_order_id(storage: &mut dyn Storage) -> Result { Ok(id) } -/// Reduces the liquidity of a tick by the specified amount and removes it if no liquidity remains. -pub fn reduce_tick_liquidity( - storage: &mut dyn Storage, - book_id: u64, - tick_id: i64, - amount: Uint128, -) -> Result<(), ContractError> { - let tick_liquidity = TICK_LIQUIDITY - .may_load(storage, &(book_id, tick_id))? - .ok_or(ContractError::InvalidTickId { tick_id })?; - let new_liquidity = tick_liquidity.checked_sub(amount)?; - if new_liquidity.is_zero() { - TICK_LIQUIDITY.remove(storage, &(book_id, tick_id)); - } else { - TICK_LIQUIDITY.save(storage, &(book_id, tick_id), &new_liquidity)?; - }; - Ok(()) -} - /// Retrieves a list of `LimitOrder` filtered by the specified `FilterOwnerOrders`. /// /// This function allows for filtering orders based on the owner's address, optionally further diff --git a/contracts/sumtree-orderbook/src/tests/test_state.rs b/contracts/sumtree-orderbook/src/tests/test_state.rs index 3e22c12..241ca55 100644 --- a/contracts/sumtree-orderbook/src/tests/test_state.rs +++ b/contracts/sumtree-orderbook/src/tests/test_state.rs @@ -1,5 +1,5 @@ use crate::state::*; -use crate::types::{FilterOwnerOrders, LimitOrder, OrderDirection}; +use crate::types::{FilterOwnerOrders, LimitOrder, OrderDirection, TickState}; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{Addr, Order, Uint128}; @@ -27,11 +27,11 @@ fn test_tick_iteration() { let book_id = new_orderbook_id(&mut storage).unwrap(); let tick_amount = 50; for i in -tick_amount..tick_amount { - TICK_LIQUIDITY - .save(&mut storage, &(book_id, i), &Uint128::new(i as u128)) + TICK_STATE + .save(&mut storage, &(book_id, i), &TickState::default()) .unwrap(); } - let prefix = TICK_LIQUIDITY.prefix(book_id); + let prefix = TICK_STATE.prefix(book_id); let ticks_asc: Vec = prefix .keys(&storage, None, None, Order::Ascending) .map(|result| result.unwrap()) diff --git a/contracts/sumtree-orderbook/src/types/mod.rs b/contracts/sumtree-orderbook/src/types/mod.rs index 30cb5df..834c2ee 100644 --- a/contracts/sumtree-orderbook/src/types/mod.rs +++ b/contracts/sumtree-orderbook/src/types/mod.rs @@ -1,7 +1,9 @@ mod order; mod orderbook; mod reply_id; +mod tick; pub use self::order::*; pub use self::orderbook::*; pub use self::reply_id::*; +pub use self::tick::*; diff --git a/contracts/sumtree-orderbook/src/types/tick.rs b/contracts/sumtree-orderbook/src/types/tick.rs new file mode 100644 index 0000000..083fd25 --- /dev/null +++ b/contracts/sumtree-orderbook/src/types/tick.rs @@ -0,0 +1,36 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Decimal256; + +/// Represents the state of a specific price tick in a liquidity pool. +#[cw_serde] +pub struct TickState { + /// Total Amount of Liquidity at tick (TAL) + /// - Every limit order placement increments this value. + /// - Every swap at this tick decrements this value. + /// - Every cancellation decrements this value. + pub total_amount_of_liquidity: Decimal256, + + /// Cumulative Total Limits at tick (CTT) + /// - Every limit order placement increments this value. + /// - There might be an edge-case optimization to lower this value. + pub cumulative_total_limits: Decimal256, + + /// Effective Total Amount Swapped at tick (ETAS) + /// - Every swap increments ETAS by the swap amount. + /// - There will be other ways to update ETAS as described below. + pub effective_total_amount_swapped: Decimal256, + // Next Limit ID at tick + // - Used to assign unique identifiers to new limit orders at this tick. + // TODO: is this necessary? + // pub next_limit_id: u64, +} + +impl Default for TickState { + fn default() -> Self { + TickState { + total_amount_of_liquidity: Decimal256::zero(), + cumulative_total_limits: Decimal256::zero(), + effective_total_amount_swapped: Decimal256::zero(), + } + } +} From 36ba3ea4b9162ebfe0e279ee04349b740a48f094 Mon Sep 17 00:00:00 2001 From: alpo Date: Fri, 15 Mar 2024 15:18:24 -0700 Subject: [PATCH 2/2] remove next limit id field --- contracts/sumtree-orderbook/src/types/tick.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/sumtree-orderbook/src/types/tick.rs b/contracts/sumtree-orderbook/src/types/tick.rs index 083fd25..12af4c1 100644 --- a/contracts/sumtree-orderbook/src/types/tick.rs +++ b/contracts/sumtree-orderbook/src/types/tick.rs @@ -19,10 +19,6 @@ pub struct TickState { /// - Every swap increments ETAS by the swap amount. /// - There will be other ways to update ETAS as described below. pub effective_total_amount_swapped: Decimal256, - // Next Limit ID at tick - // - Used to assign unique identifiers to new limit orders at this tick. - // TODO: is this necessary? - // pub next_limit_id: u64, } impl Default for TickState {