Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
crispheaney committed Dec 29, 2023
1 parent 2b6a054 commit fbdcef6
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 4 deletions.
11 changes: 7 additions & 4 deletions programs/drift/src/state/order_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use anchor_lang::prelude::*;
use borsh::{BorshDeserialize, BorshSerialize};
use std::ops::Div;

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Copy)]
#[cfg(test)]
mod tests;

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Copy, Eq, PartialEq, Debug)]
pub struct OrderParams {
pub order_type: OrderType,
pub market_type: MarketType,
Expand Down Expand Up @@ -62,7 +65,7 @@ impl OrderParams {
let est_ask = oracle_price.safe_add(ask_premium)?.cast()?;
if self.price > est_ask {
let auction_duration =
get_auction_duration(self.price.safe_sub(est_ask)?, self.price)?;
get_auction_duration(self.price.safe_sub(est_ask)?, est_ask)?;

Check warning on line 68 in programs/drift/src/state/order_params.rs

View check run for this annotation

Codecov / codecov/patch

programs/drift/src/state/order_params.rs#L68

Added line #L68 was not covered by tests
let auction_start_price = est_ask as i64;
let auction_end_price = self.price as i64;
msg!("derived auction params for limit order. duration = {} start_price = {} end_price = {}", auction_duration, auction_start_price, auction_end_price);
Expand All @@ -76,7 +79,7 @@ impl OrderParams {
let est_bid = oracle_price.safe_sub(bid_discount)?.cast()?;
if self.price < est_bid {
let auction_duration =
get_auction_duration(est_bid.safe_sub(self.price)?, self.price)?;
get_auction_duration(est_bid.safe_sub(self.price)?, est_bid)?;

Check warning on line 82 in programs/drift/src/state/order_params.rs

View check run for this annotation

Codecov / codecov/patch

programs/drift/src/state/order_params.rs#L82

Added line #L82 was not covered by tests
let auction_start_price = est_bid as i64;
let auction_end_price = self.price as i64;
msg!("derived auction params for limit order. duration = {} start_price = {} end_price = {}", auction_duration, auction_start_price, auction_end_price);
Expand All @@ -96,7 +99,7 @@ fn get_auction_duration(price_diff: u64, price: u64) -> DriftResult<u8> {

Ok(percent_diff
.safe_mul(60)?
.safe_div(PERCENTAGE_PRECISION_U64 / 100)? // 1% = 60 seconds
.safe_div_ceil(PERCENTAGE_PRECISION_U64 / 100)? // 1% = 60 seconds

Check warning on line 102 in programs/drift/src/state/order_params.rs

View check run for this annotation

Codecov / codecov/patch

programs/drift/src/state/order_params.rs#L101-L102

Added lines #L101 - L102 were not covered by tests
.clamp(10, 60) as u8)
}

Expand Down
223 changes: 223 additions & 0 deletions programs/drift/src/state/order_params/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
mod get_auction_duration {
use crate::state::order_params::get_auction_duration;
use crate::PRICE_PRECISION_U64;

#[test]
fn test() {
let price_diff = 0;
let price = 100 * PRICE_PRECISION_U64;

let duration = get_auction_duration(price_diff, price).unwrap();
assert_eq!(duration, 10);

let price_diff = PRICE_PRECISION_U64 / 10;
let price = 100 * PRICE_PRECISION_U64;

let duration = get_auction_duration(price_diff, price).unwrap();
assert_eq!(duration, 10);

let price_diff = PRICE_PRECISION_U64 / 2;
let price = 100 * PRICE_PRECISION_U64;

let duration = get_auction_duration(price_diff, price).unwrap();
assert_eq!(duration, 30);

let price_diff = PRICE_PRECISION_U64;
let price = 100 * PRICE_PRECISION_U64;

let duration = get_auction_duration(price_diff, price).unwrap();
assert_eq!(duration, 60);

let price_diff = 2 * PRICE_PRECISION_U64;
let price = 100 * PRICE_PRECISION_U64;

let duration = get_auction_duration(price_diff, price).unwrap();
assert_eq!(duration, 60);
}
}

mod update_perp_auction_params {
use crate::state::order_params::PostOnlyParam;
use crate::state::perp_market::{PerpMarket, AMM};
use crate::state::user::OrderType;
use crate::{
OrderParams, PositionDirection, AMM_RESERVE_PRECISION, BID_ASK_SPREAD_PRECISION,
PEG_PRECISION, PRICE_PRECISION_I64, PRICE_PRECISION_U64,
};

#[test]
fn test() {
let oracle_price = 100 * PRICE_PRECISION_I64;
let mut amm = AMM {
base_asset_reserve: 100 * AMM_RESERVE_PRECISION,
quote_asset_reserve: 100 * AMM_RESERVE_PRECISION,
short_spread: (BID_ASK_SPREAD_PRECISION / 100) as u32,
long_spread: (BID_ASK_SPREAD_PRECISION / 100) as u32,
sqrt_k: 100 * AMM_RESERVE_PRECISION,
peg_multiplier: 100 * PEG_PRECISION,
..AMM::default()
};
amm.historical_oracle_data.last_oracle_price = oracle_price;
let perp_market = PerpMarket {
amm,
..PerpMarket::default()
};

let order_params_before = OrderParams {
order_type: OrderType::Market,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: Some(0),
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::MustPostOnly,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: true,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: false,
oracle_price_offset: Some(0),
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: false,
oracle_price_offset: None,
price: 0,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: false,
oracle_price_offset: None,
price: 100 * PRICE_PRECISION_U64,
direction: PositionDirection::Long,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: false,
oracle_price_offset: None,
price: 102 * PRICE_PRECISION_U64,
direction: PositionDirection::Long,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_ne!(order_params_before, order_params_after);
assert_eq!(order_params_after.auction_duration, Some(60));
assert_eq!(
order_params_after.auction_start_price,
Some(101 * PRICE_PRECISION_I64)
);
assert_eq!(
order_params_after.auction_end_price,
Some(102 * PRICE_PRECISION_I64)
);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: false,
oracle_price_offset: None,
price: 100 * PRICE_PRECISION_U64,
direction: PositionDirection::Short,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_eq!(order_params_before, order_params_after);

let order_params_before = OrderParams {
order_type: OrderType::Limit,
auction_duration: None,
post_only: PostOnlyParam::None,
immediate_or_cancel: false,
oracle_price_offset: None,
price: 98 * PRICE_PRECISION_U64,
direction: PositionDirection::Short,
..OrderParams::default()
};
let mut order_params_after = order_params_before;
order_params_after
.update_perp_auction_params(&perp_market, oracle_price)
.unwrap();
assert_ne!(order_params_before, order_params_after);
assert_eq!(order_params_after.auction_duration, Some(60));
assert_eq!(
order_params_after.auction_start_price,
Some(99 * PRICE_PRECISION_I64)
);
assert_eq!(
order_params_after.auction_end_price,
Some(98 * PRICE_PRECISION_I64)
);
}
}
3 changes: 3 additions & 0 deletions programs/drift/src/state/perp_market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ use borsh::{BorshDeserialize, BorshSerialize};
use drift_macros::assert_no_slop;
use static_assertions::const_assert_eq;

#[cfg(test)]
mod tests;

#[derive(Clone, Copy, BorshSerialize, BorshDeserialize, PartialEq, Debug, Eq)]
pub enum MarketStatus {
/// warm up period for initialization, fills are paused
Expand Down
42 changes: 42 additions & 0 deletions programs/drift/src/state/perp_market/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
mod amm {
use crate::state::perp_market::AMM;
use crate::{
AMM_RESERVE_PRECISION, BID_ASK_SPREAD_PRECISION, PEG_PRECISION, PRICE_PRECISION_I64,
};

#[test]
fn last_ask_premium() {
let mut amm = AMM {
base_asset_reserve: 100 * AMM_RESERVE_PRECISION,
quote_asset_reserve: 100 * AMM_RESERVE_PRECISION,
short_spread: (BID_ASK_SPREAD_PRECISION / 10) as u32,
long_spread: (BID_ASK_SPREAD_PRECISION / 10) as u32,
sqrt_k: 100 * AMM_RESERVE_PRECISION,
peg_multiplier: 100 * PEG_PRECISION,
..AMM::default()
};
amm.historical_oracle_data.last_oracle_price = 100 * PRICE_PRECISION_I64;

let premium = amm.last_ask_premium().unwrap();

assert_eq!(premium, 10000000); // $1
}

#[test]
fn last_bid_discount() {
let mut amm = AMM {
base_asset_reserve: 100 * AMM_RESERVE_PRECISION,
quote_asset_reserve: 100 * AMM_RESERVE_PRECISION,
short_spread: (BID_ASK_SPREAD_PRECISION / 10) as u32,
long_spread: (BID_ASK_SPREAD_PRECISION / 10) as u32,
sqrt_k: 100 * AMM_RESERVE_PRECISION,
peg_multiplier: 100 * PEG_PRECISION,
..AMM::default()
};
amm.historical_oracle_data.last_oracle_price = 100 * PRICE_PRECISION_I64;

let discount = amm.last_bid_discount().unwrap();

assert_eq!(discount, 10000000); // $1
}
}

0 comments on commit fbdcef6

Please sign in to comment.