Skip to content

Commit

Permalink
Merge pull request #61 from osmosis-labs/sumtree/tick-state
Browse files Browse the repository at this point in the history
[Sumtree]: Tick State
  • Loading branch information
crnbarr93 authored Mar 20, 2024
2 parents 7647145 + 36ba3ea commit 5db8a14
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 36 deletions.
17 changes: 7 additions & 10 deletions contracts/sumtree-orderbook/src/order.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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::<Uint128, ContractError>(
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())
Expand Down
25 changes: 3 additions & 22 deletions contracts/sumtree-orderbook/src/state.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<Index Key: owner, Input Data: LimitOrder, Map Key: (orderbook_id, tick, order_id)>
Expand Down Expand Up @@ -68,25 +68,6 @@ pub fn new_order_id(storage: &mut dyn Storage) -> Result<u64, ContractError> {
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
Expand Down
8 changes: 4 additions & 4 deletions contracts/sumtree-orderbook/src/tests/test_state.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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<i64> = prefix
.keys(&storage, None, None, Order::Ascending)
.map(|result| result.unwrap())
Expand Down
2 changes: 2 additions & 0 deletions contracts/sumtree-orderbook/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -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::*;
32 changes: 32 additions & 0 deletions contracts/sumtree-orderbook/src/types/tick.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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,
}

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(),
}
}
}

0 comments on commit 5db8a14

Please sign in to comment.