Skip to content

Commit

Permalink
Added test for market order [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
crnbarr93 committed Feb 19, 2024
1 parent 6743890 commit 6c18090
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 8 deletions.
10 changes: 5 additions & 5 deletions contracts/orderbook/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ pub fn run_market_order(
let mut fulfilments: Vec<Fulfilment> = vec![];
let mut amount_fulfiled: Uint128 = Uint128::zero();
let orderbook = ORDERBOOKS.load(storage, &order.book_id)?;
let first_tick = orderbook.next_bid_tick;
let placed_order_denom = orderbook.get_expected_denom(&order.order_direction);

let (min_tick, max_tick, ordering) = match order.order_direction {
OrderDirection::Bid => (Some(first_tick), tick_bound, Order::Ascending),
OrderDirection::Ask => (tick_bound, Some(first_tick), Order::Descending),
OrderDirection::Ask => (Some(orderbook.next_bid_tick), tick_bound, Order::Ascending),
OrderDirection::Bid => (tick_bound, Some(orderbook.next_ask_tick), Order::Descending),
};

// Create ticks iterator between first tick and requested tick
// TODO: Remove filter map and map
let ticks = TICK_LIQUIDITY
.prefix(order.book_id)
.range(
Expand Down Expand Up @@ -213,9 +213,9 @@ pub fn run_market_order(
let fulfilment = Fulfilment::new(current_order, fill_quantity);
fulfilments.push(fulfilment);

order.quantity = order.quantity.checked_sub(fill_quantity)?;
// TODO: Price detection
if order.quantity.is_zero() {
order.quantity -= amount_fulfiled;
return Ok((
fulfilments,
BankMsg::Send {
Expand All @@ -239,7 +239,7 @@ pub fn run_market_order(
}
}

order.quantity -= amount_fulfiled;
order.quantity = order.quantity.checked_sub(amount_fulfiled)?;

// TODO: Price detection
Ok((
Expand Down
125 changes: 122 additions & 3 deletions contracts/orderbook/src/tests/test_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::orderbook::*;
use crate::state::*;
use crate::types::Fulfilment;
use crate::types::LimitOrder;
use crate::types::MarketOrder;
use crate::types::OrderDirection;
use crate::types::REPLY_ID_REFUND;
use cosmwasm_std::testing::{mock_dependencies_with_balances, mock_env, mock_info};
Expand Down Expand Up @@ -557,7 +558,7 @@ struct ResolveFulfilmentsTestCase {
}

#[test]
fn test_run_resolve_fulfilments() {
fn test_resolve_fulfilments() {
let valid_book_id = 0;
let test_cases: Vec<ResolveFulfilmentsTestCase> = vec![
ResolveFulfilmentsTestCase {
Expand Down Expand Up @@ -731,8 +732,7 @@ fn test_run_resolve_fulfilments() {
];

for test in test_cases {
let balances = [];
let mut deps = mock_dependencies_with_balances(&balances);
let mut deps = mock_dependencies_with_balances(&[]);
let env = mock_env();
let info = mock_info("maker", &[]);

Expand Down Expand Up @@ -778,9 +778,12 @@ fn test_run_resolve_fulfilments() {

let response = resolve_fulfilments(deps.as_mut().storage, fulfilments);

// -- POST STATE --

if let Some(expected_error) = &test.expected_error {
let err = response.unwrap_err();
assert_eq!(err, *expected_error, "{}", format_test_name(test.name));
// NOTE: We cannot check if orders/tick liquidity were unaltered as changes are made in a for loop that is not rolled back upon error

continue;
}
Expand Down Expand Up @@ -811,6 +814,7 @@ fn test_run_resolve_fulfilments() {
.unwrap();

let response = response.unwrap();

for (idx, (Fulfilment { order, amount }, removed)) in test.fulfilments.iter().enumerate() {
let saved_order = orders()
.may_load(
Expand Down Expand Up @@ -844,3 +848,118 @@ fn test_run_resolve_fulfilments() {
}
}
}

struct RunMarketOrderTestCase {
pub name: &'static str,
pub placed_order: MarketOrder,
pub tick_bound: Option<i64>,
pub expected_fulfilments: Vec<Fulfilment>,
pub expected_error: Option<ContractError>,
}

#[test]
fn test_run_market_order() {
let valid_book_id = 0;
let test_cases: Vec<RunMarketOrderTestCase> = vec![RunMarketOrderTestCase {
name: "standard market order (single tick)",
placed_order: MarketOrder::new(
valid_book_id,
Uint128::from(100u128),
OrderDirection::Ask,
Addr::unchecked("creator"),
),
tick_bound: None,
expected_fulfilments: vec![
Fulfilment::new(
LimitOrder::new(
valid_book_id,
-1,
0,
OrderDirection::Bid,
Addr::unchecked("creator"),
Uint128::from(50u128),
),
Uint128::from(50u128),
),
Fulfilment::new(
LimitOrder::new(
valid_book_id,
-1,
1,
OrderDirection::Bid,
Addr::unchecked("creator"),
Uint128::from(150u128),
),
Uint128::from(50u128),
),
],
expected_error: None,
}];

for test in test_cases {
let mut deps = mock_dependencies_with_balances(&[]);
let env = mock_env();
let info = mock_info("maker", &[]);

// Create an orderbook to operate on
let quote_denom = "quote".to_string();
let base_denom = "base".to_string();
create_orderbook(
deps.as_mut(),
env.clone(),
info.clone(),
quote_denom.clone(),
base_denom.clone(),
)
.unwrap();

let fulfilments = test.expected_fulfilments.to_vec();

// Add orders to state
for Fulfilment { order, .. } in fulfilments.clone() {
orders()
.save(
deps.as_mut().storage,
&(order.book_id, order.tick_id, order.order_id),
&order,
)
.unwrap();
TICK_LIQUIDITY
.update(
deps.as_mut().storage,
&(order.book_id, order.tick_id),
|l| {
Ok::<Uint128, ContractError>(
l.unwrap_or_default().checked_add(order.quantity).unwrap(),
)
},
)
.unwrap();
}

let mut market_order = test.placed_order.clone();
let response = run_market_order(deps.as_mut().storage, &mut market_order, test.tick_bound);

// -- POST STATE --

if let Some(expected_error) = &test.expected_error {
let err = response.unwrap_err();
assert_eq!(err, *expected_error, "{}", format_test_name(test.name));
// NOTE: We cannot check if orders/tick liquidity were unaltered as changes are made in a for loop that is not rolled back upon error

continue;
}

let response = response.unwrap();

for (idx, fulfilment) in test.expected_fulfilments.iter().enumerate() {
// Check message is generated as expected
assert_eq!(
response.0[idx],
*fulfilment,
"{}",
format_test_name(test.name)
);
}
}
}
16 changes: 16 additions & 0 deletions contracts/orderbook/src/types/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ pub struct MarketOrder {
pub owner: Addr,
}

impl MarketOrder {
pub fn new(
book_id: u64,
quantity: Uint128,
order_direction: OrderDirection,
owner: Addr,
) -> Self {
MarketOrder {
book_id,
quantity,
order_direction,
owner,
}
}
}

impl From<LimitOrder> for MarketOrder {
fn from(limit_order: LimitOrder) -> Self {
MarketOrder {
Expand Down

0 comments on commit 6c18090

Please sign in to comment.