diff --git a/contracts/sumtree-orderbook/Cargo.toml b/contracts/sumtree-orderbook/Cargo.toml index 9eed4dc..9560c60 100644 --- a/contracts/sumtree-orderbook/Cargo.toml +++ b/contracts/sumtree-orderbook/Cargo.toml @@ -56,7 +56,7 @@ osmosis-std = "0.16.0" prost = { version = "0.11.2", default-features = false, features = [ "prost-derive", ] } - +lazy_static = "1.4.0" [dev-dependencies] cw-multi-test = "0.18.0" diff --git a/contracts/sumtree-orderbook/src/constants.rs b/contracts/sumtree-orderbook/src/constants.rs index 1afe897..129ad2c 100644 --- a/contracts/sumtree-orderbook/src/constants.rs +++ b/contracts/sumtree-orderbook/src/constants.rs @@ -1,4 +1,5 @@ use cosmwasm_std::{Decimal, Decimal256}; +use lazy_static::lazy_static; use std::str::FromStr; pub const MIN_TICK: i64 = -108000000; @@ -10,11 +11,8 @@ pub const EXPECTED_SWAP_FEE: Decimal = Decimal::zero(); pub const MAX_BATCH_CLAIM: u32 = 100; pub const MAX_MAKER_FEE_PERCENTAGE: Decimal256 = Decimal256::percent(5); -// TODO: optimize this using lazy_static -pub fn max_spot_price() -> Decimal256 { - Decimal256::from_str("340282300000000000000").unwrap() -} - -pub fn min_spot_price() -> Decimal256 { - Decimal256::from_str("0.000000000001").unwrap() +lazy_static! { + pub static ref MAX_SPOT_PRICE: Decimal256 = + Decimal256::from_str("340282300000000000000").unwrap(); + pub static ref MIN_SPOT_PRICE: Decimal256 = Decimal256::from_str("0.000000000001").unwrap(); } diff --git a/contracts/sumtree-orderbook/src/order.rs b/contracts/sumtree-orderbook/src/order.rs index a9825f9..e484dbf 100644 --- a/contracts/sumtree-orderbook/src/order.rs +++ b/contracts/sumtree-orderbook/src/order.rs @@ -1,4 +1,4 @@ -use crate::constants::{MAX_BATCH_CLAIM, MAX_TICK, MIN_TICK}; +use crate::constants::{MAX_BATCH_CLAIM, MAX_SPOT_PRICE, MAX_TICK, MIN_SPOT_PRICE, MIN_TICK}; use crate::error::{ContractError, ContractResult}; use crate::state::{ add_directional_liquidity, get_maker_fee, new_order_id, orders, subtract_directional_liquidity, @@ -55,6 +55,22 @@ pub fn place_limit( ); } + // The boundary max/min spot price given order direction + let boundary_spot_price = match order_direction { + OrderDirection::Bid => *MAX_SPOT_PRICE, + OrderDirection::Ask => *MIN_SPOT_PRICE, + }; + // The epxected price when this order is claimed + let claimed_price = amount_to_value( + order_direction, + quantity, + boundary_spot_price, + RoundingDirection::Down, + ); + + // If claimed_price returns an error then the order cannot be claimed + ensure!(claimed_price.is_ok(), ContractError::MaxSpotPriceExceeded); + // Determine the correct denom based on order direction let expected_denom = orderbook.get_expected_denom(&order_direction); diff --git a/contracts/sumtree-orderbook/src/tests/test_tick_math.rs b/contracts/sumtree-orderbook/src/tests/test_tick_math.rs index a763bf0..7ba1ba9 100644 --- a/contracts/sumtree-orderbook/src/tests/test_tick_math.rs +++ b/contracts/sumtree-orderbook/src/tests/test_tick_math.rs @@ -26,7 +26,7 @@ fn test_tick_to_price() { let tick_price_test_cases = vec![ TickToPriceTestCase { tick_index: MAX_TICK, - expected_price: max_spot_price(), + expected_price: *MAX_SPOT_PRICE, expected_error: None, }, TickToPriceTestCase { @@ -66,14 +66,14 @@ fn test_tick_to_price() { }, TickToPriceTestCase { tick_index: MAX_TICK - 1, - expected_price: max_spot_price() + expected_price: MAX_SPOT_PRICE .checked_sub(min_increment_near_max_price) .unwrap(), expected_error: None, }, TickToPriceTestCase { tick_index: MIN_TICK, - expected_price: min_spot_price(), + expected_price: *MIN_SPOT_PRICE, expected_error: None, }, TickToPriceTestCase {