Skip to content

Commit

Permalink
Merge pull request #191 from osmosis-labs/connor/e2e-testing
Browse files Browse the repository at this point in the history
[Sumtree]: E2E and Fuzz Testing
  • Loading branch information
crnbarr93 authored Jul 5, 2024
2 parents cd637d0 + 5c1911a commit 72ce4b5
Show file tree
Hide file tree
Showing 23 changed files with 4,573 additions and 424 deletions.
2,395 changes: 2,137 additions & 258 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion contracts/sumtree-orderbook/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ rpath = false
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
skip-integration-tests = []

[package.metadata.scripts]
optimize = """docker run --rm -v "$(pwd)":/code \
Expand All @@ -52,12 +53,13 @@ schemars = "0.8.15"
serde = { version = "1.0.189", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.49" }
osmosis-std-derive = "0.15.3"
osmosis-std = "0.16.0"
osmosis-std = "0.25.0"
prost = { version = "0.11.2", default-features = false, features = [
"prost-derive",
] }


[dev-dependencies]
cw-multi-test = "0.18.0"
osmosis-test-tube = { version = "25.0.0", features = ["wasm-sudo"] }
rand = "0.8.4"
1 change: 1 addition & 0 deletions contracts/sumtree-orderbook/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult<Binary> {
} => Ok(to_json_binary(&query::orders_by_owner(
deps, owner, start_from, end_at, limit,
)?)?),
QueryMsg::OrderbookState {} => Ok(to_json_binary(&query::orderbook_state(deps)?)?),
QueryMsg::TicksById { tick_ids } => {
Ok(to_json_binary(&query::ticks_by_id(deps, tick_ids)?)?)
}
Expand Down
5 changes: 4 additions & 1 deletion contracts/sumtree-orderbook/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub enum QueryMsg {
#[returns(bool)]
IsActive {},

#[returns(Vec<crate::types::LimitOrder>)]
#[returns(OrdersResponse)]
OrdersByOwner {
// The address of the order maker
owner: Addr,
Expand All @@ -129,6 +129,9 @@ pub enum QueryMsg {
limit: Option<u64>,
},

#[returns(crate::types::Orderbook)]
OrderbookState {},

#[returns(DenomsResponse)]
Denoms {},

Expand Down
10 changes: 7 additions & 3 deletions contracts/sumtree-orderbook/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ pub fn place_limit(
.with_placed_at(env.block.time);

let quant_dec256 = Decimal256::from_ratio(limit_order.quantity.u128(), Uint256::one());

// Save the order to the orderbook
orders().save(deps.storage, &(tick_id, order_id), &limit_order)?;

Expand Down Expand Up @@ -166,7 +165,6 @@ pub fn cancel_limit(
.effective_total_amount_swapped,
)?;

// Ensure the order has not been filled.
let tick_state = TICK_STATE.load(deps.storage, tick_id).unwrap_or_default();
let tick_values = tick_state.get_values(order.order_direction);
ensure!(
Expand Down Expand Up @@ -213,10 +211,10 @@ pub fn cancel_limit(
);

orders().remove(deps.storage, &(order.tick_id, order.order_id))?;

curr_tick_values.total_amount_of_liquidity = curr_tick_values
.total_amount_of_liquidity
.checked_sub(Decimal256::from_ratio(order.quantity, Uint256::one()))?;

curr_tick_state.set_values(order.order_direction, curr_tick_values);
TICK_STATE.save(deps.storage, order.tick_id, &curr_tick_state)?;
subtract_directional_liquidity(deps.storage, order.order_direction, quant_dec256)?;
Expand Down Expand Up @@ -503,6 +501,11 @@ pub(crate) fn run_market_order_internal(
let current_tick_id = maybe_current_tick?;
let mut current_tick = TICK_STATE.load(storage, current_tick_id)?;
let mut current_tick_values = current_tick.get_values(order.order_direction.opposite());

if current_tick_values.total_amount_of_liquidity.is_zero() {
continue;
}

let tick_price = tick_to_price(current_tick_id)?;
last_tick_price = tick_price;

Expand Down Expand Up @@ -634,6 +637,7 @@ pub(crate) fn claim_order(
// Sync the tick the order is on to ensure correct ETAS
let bid_tick_values = tick_state.get_values(OrderDirection::Bid);
let ask_tick_values = tick_state.get_values(OrderDirection::Ask);

sync_tick(
storage,
tick_id,
Expand Down
25 changes: 20 additions & 5 deletions contracts/sumtree-orderbook/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
sudo::ensure_swap_fee,
sumtree::tree::{get_prefix_sum, get_root_node},
tick_math::tick_to_price,
types::{FilterOwnerOrders, LimitOrder, MarketOrder, OrderDirection, TickState},
types::{FilterOwnerOrders, MarketOrder, OrderDirection, Orderbook, TickState},
ContractError,
};

Expand Down Expand Up @@ -60,8 +60,8 @@ pub(crate) fn spot_price(
let price = tick_to_price(next_tick)?;

let spot_price = match direction {
OrderDirection::Ask => price.inv().unwrap(),
OrderDirection::Bid => price,
OrderDirection::Ask => price,
OrderDirection::Bid => price.inv().unwrap(),
};

Ok(SpotPriceResponse {
Expand Down Expand Up @@ -205,15 +205,25 @@ pub(crate) fn orders_by_owner(
start_from: Option<(i64, u64)>,
end_at: Option<(i64, u64)>,
limit: Option<u64>,
) -> ContractResult<Vec<LimitOrder>> {
) -> ContractResult<OrdersResponse> {
let count = orders()
.idx
.owner
.prefix(owner.clone())
.keys(deps.storage, None, None, Order::Ascending)
.count();
let orders = get_orders_by_owner(
deps.storage,
FilterOwnerOrders::all(owner),
start_from,
end_at,
limit,
)?;
Ok(orders)

Ok(OrdersResponse {
count: count as u64,
orders,
})
}

pub(crate) fn denoms(deps: Deps) -> ContractResult<DenomsResponse> {
Expand All @@ -224,6 +234,11 @@ pub(crate) fn denoms(deps: Deps) -> ContractResult<DenomsResponse> {
})
}

pub(crate) fn orderbook_state(deps: Deps) -> ContractResult<Orderbook> {
let orderbook = ORDERBOOK.load(deps.storage)?;
Ok(orderbook)
}

pub(crate) fn ticks_by_id(deps: Deps, tick_ids: Vec<i64>) -> ContractResult<TicksResponse> {
let mut ticks: Vec<TickIdAndState> = vec![];
for tick_id in tick_ids {
Expand Down
2 changes: 1 addition & 1 deletion contracts/sumtree-orderbook/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub fn get_orders_by_owner(
page_size: Option<u64>,
) -> StdResult<Vec<LimitOrder>> {
let page_size = page_size.unwrap_or(DEFAULT_PAGE_SIZE) as usize;
let min = min.map(Bound::exclusive);
let min = min.map(Bound::inclusive);
let max = max.map(Bound::inclusive);

// Define the prefix iterator based on the filter
Expand Down
1 change: 1 addition & 0 deletions contracts/sumtree-orderbook/src/sumtree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub fn get_prefix_sum(
// Since the longest path this function can walk is from the root to a leaf, it runs in O(log(N)) time. Given
// how it is able to terminate early using our sumtree's range properties, in many cases it will likely run
// in much less.

fn prefix_sum_walk(
storage: &dyn Storage,
node: &TreeNode,
Expand Down
2 changes: 2 additions & 0 deletions contracts/sumtree-orderbook/src/tests/e2e/cases/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod test_fuzz;
mod test_orders;
Loading

0 comments on commit 72ce4b5

Please sign in to comment.