Skip to content

Commit

Permalink
Abstracted method for mapping order direction to tick math
Browse files Browse the repository at this point in the history
  • Loading branch information
crnbarr93 committed Feb 27, 2024
1 parent cb4c27c commit 4bc6026
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 7 deletions.
9 changes: 6 additions & 3 deletions contracts/orderbook/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::constants::{MAX_TICK, MIN_TICK};
use crate::error::ContractError;
use crate::state::ORDERBOOKS;
use crate::state::*;
use crate::tick_math::{multiply_by_price, tick_to_price};
use crate::tick_math::{amount_to_value, tick_to_price};
use crate::types::{Fulfillment, LimitOrder, MarketOrder, OrderDirection, REPLY_ID_REFUND};
use cosmwasm_std::{
coin, ensure, ensure_eq, ensure_ne, BankMsg, Decimal256, DepsMut, Env, MessageInfo, Order,
Expand Down Expand Up @@ -221,8 +221,11 @@ pub fn run_market_order(
let fill_quantity = order.quantity.min(current_order.quantity);
// Add to total amount fulfilled from placed order
amount_fulfilled = amount_fulfilled.checked_add(fill_quantity)?;
amount_to_send =
amount_to_send.checked_add(multiply_by_price(amount_fulfilled, tick_price)?)?;
amount_to_send = amount_to_send.checked_add(amount_to_value(
order.order_direction,
amount_fulfilled,
tick_price,
)?)?;
// Generate fulfillment for current order
let fulfillment = Fulfillment::new(current_order, fill_quantity);
fulfillments.push(fulfillment);
Expand Down
4 changes: 2 additions & 2 deletions contracts/orderbook/src/tests/test_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
types::{Fulfillment, LimitOrder, MarketOrder, OrderDirection, REPLY_ID_REFUND},
};
use cosmwasm_std::testing::{mock_dependencies_with_balances, mock_env, mock_info};
use cosmwasm_std::{coin, Addr, BankMsg, Coin, Decimal, Empty, SubMsg, Uint128};
use cosmwasm_std::{coin, Addr, BankMsg, Coin, Empty, SubMsg, Uint128};
use cw_utils::PaymentError;

#[allow(clippy::uninlined_format_args)]
Expand Down Expand Up @@ -577,7 +577,7 @@ fn test_resolve_fulfillments() {
Fulfillment::new(
LimitOrder::new(
0,
MAX_TICK,
1,
1,
OrderDirection::Bid,
Addr::unchecked("creator"),
Expand Down
22 changes: 22 additions & 0 deletions contracts/orderbook/src/tick_math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::constants::{
EXPONENT_AT_PRICE_ONE, GEOMETRIC_EXPONENT_INCREMENT_DISTANCE_IN_TICKS, MAX_TICK, MIN_TICK,
};
use crate::error::*;
use crate::types::OrderDirection;
use cosmwasm_std::{ensure, Decimal256, Uint128, Uint256};

// tick_to_price converts a tick index to a price.
Expand Down Expand Up @@ -92,3 +93,24 @@ pub fn multiply_by_price(amount: Uint128, price: Decimal256) -> ContractResult<U

Ok(amount_to_send)
}

// Divides a given tick amount by the price for that tick
pub fn divide_by_price(amount: Uint128, price: Decimal256) -> ContractResult<Uint128> {
let amount_to_send_u256 = price
.checked_div(Decimal256::new(Uint256::from(amount)))?
.to_uint_ceil();
let amount_to_send = Uint128::from_str(amount_to_send_u256.to_string().as_str()).unwrap();

Ok(amount_to_send)
}

pub fn amount_to_value(
order: OrderDirection,
amount: Uint128,
price: Decimal256,
) -> ContractResult<Uint128> {
match order {
OrderDirection::Bid => divide_by_price(amount, price),
OrderDirection::Ask => multiply_by_price(amount, price),
}
}
6 changes: 4 additions & 2 deletions contracts/orderbook/src/types/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use cosmwasm_schema::cw_serde;
use cosmwasm_std::{coin, ensure, Addr, BankMsg, Uint128};

use crate::{
tick_math::{multiply_by_price, tick_to_price},
tick_math::{amount_to_value, tick_to_price},
ContractError,
};

Expand Down Expand Up @@ -59,8 +59,10 @@ impl LimitOrder {
}
);
self.quantity = self.quantity.checked_sub(quantity)?;
// Determine price
let price = tick_to_price(self.tick_id)?;
let amount_to_send = multiply_by_price(quantity, price)?;
// Multiply quantity by price
let amount_to_send = amount_to_value(self.order_direction, quantity, price)?;
Ok(BankMsg::Send {
to_address: self.owner.to_string(),
amount: vec![coin(amount_to_send.u128(), denom.into())],
Expand Down

0 comments on commit 4bc6026

Please sign in to comment.