Skip to content

Commit

Permalink
program: better derivation of perp auction params when missing and fo…
Browse files Browse the repository at this point in the history
…r triggers(#869)

* program: new override for market orders without auction params

* use derivation logic for market orders

* get rid trigger limit hook

* CHANGELOG
  • Loading branch information
crispheaney committed Feb 8, 2024
1 parent adb90df commit 8fcabd1
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 153 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- program: better derivation of perp auction params when missing and for triggers ([#869](https://github.com/drift-labs/protocol-v2/pull/869))
- program: calculate whether oracle's num quoters sufficient ([#860](https://github.com/drift-labs/protocol-v2/pull/860))

### Fixes
Expand Down
14 changes: 11 additions & 3 deletions programs/drift/src/controller/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2598,7 +2598,8 @@ pub fn trigger_order(
&mut user.orders[order_index],
oracle_price_data,
slot,
state.min_perp_auction_duration,
30,
Some(&perp_market),
)?;

if user.orders[order_index].has_auction() {
Expand Down Expand Up @@ -2692,6 +2693,7 @@ fn update_trigger_order_params(
oracle_price_data: &OraclePriceData,
slot: u64,
min_auction_duration: u8,
perp_market: Option<&PerpMarket>,
) -> DriftResult {
order.trigger_condition = match order.trigger_condition {
OrderTriggerCondition::Above => OrderTriggerCondition::TriggeredAbove,
Expand All @@ -2704,7 +2706,12 @@ fn update_trigger_order_params(
order.slot = slot;

let (auction_duration, auction_start_price, auction_end_price) =
calculate_auction_params_for_trigger_order(order, oracle_price_data, min_auction_duration)?;
calculate_auction_params_for_trigger_order(
order,
oracle_price_data,
min_auction_duration,
perp_market,
)?;

order.auction_duration = auction_duration;
order.auction_start_price = auction_start_price;
Expand Down Expand Up @@ -4696,7 +4703,8 @@ pub fn trigger_spot_order(
&mut user.orders[order_index],
oracle_price_data,
slot,
state.default_spot_auction_duration,
30,
None,
)?;

if user.orders[order_index].has_auction() {
Expand Down
38 changes: 30 additions & 8 deletions programs/drift/src/controller/orders/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10488,8 +10488,14 @@ pub mod update_trigger_order_params {
let slot = 10;
let min_auction_duration = 10;

update_trigger_order_params(&mut order, &oracle_price_data, slot, min_auction_duration)
.unwrap();
update_trigger_order_params(
&mut order,
&oracle_price_data,
slot,
min_auction_duration,
None,
)
.unwrap();

assert_eq!(order.slot, slot);
assert_eq!(order.auction_duration, min_auction_duration);
Expand All @@ -10507,8 +10513,14 @@ pub mod update_trigger_order_params {
..Order::default()
};

update_trigger_order_params(&mut order, &oracle_price_data, slot, min_auction_duration)
.unwrap();
update_trigger_order_params(
&mut order,
&oracle_price_data,
slot,
min_auction_duration,
None,
)
.unwrap();

assert_eq!(order.slot, slot);
assert_eq!(order.auction_duration, min_auction_duration);
Expand All @@ -10526,8 +10538,13 @@ pub mod update_trigger_order_params {
..Order::default()
};

let err =
update_trigger_order_params(&mut order, &oracle_price_data, slot, min_auction_duration);
let err = update_trigger_order_params(
&mut order,
&oracle_price_data,
slot,
min_auction_duration,
None,
);
assert!(err.is_err());

let mut order = Order {
Expand All @@ -10537,8 +10554,13 @@ pub mod update_trigger_order_params {
..Order::default()
};

let err =
update_trigger_order_params(&mut order, &oracle_price_data, slot, min_auction_duration);
let err = update_trigger_order_params(
&mut order,
&oracle_price_data,
slot,
min_auction_duration,
None,
);
assert!(err.is_err());
}
}
Expand Down
33 changes: 19 additions & 14 deletions programs/drift/src/math/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::state::oracle::OraclePriceData;
use crate::state::user::{Order, OrderType};
use solana_program::msg;

use crate::state::perp_market::PerpMarket;
use crate::OrderParams;
use std::cmp::min;

#[cfg(test)]
Expand Down Expand Up @@ -218,23 +220,26 @@ pub fn calculate_auction_params_for_trigger_order(
order: &Order,
oracle_price_data: &OraclePriceData,
min_auction_duration: u8,
perp_market: Option<&PerpMarket>,
) -> DriftResult<(u8, i64, i64)> {
// if trigger limit doesn't cross oracle, no auction
if order.order_type == OrderType::TriggerLimit {
let limit_doesnt_cross_trigger = match order.direction {
PositionDirection::Long => order.price < order.trigger_price,
PositionDirection::Short => order.price > order.trigger_price,
};
let auction_duration = min_auction_duration;

if limit_doesnt_cross_trigger {
return Ok((0, 0, 0));
}
}
if let Some(perp_market) = perp_market {
let (auction_start_price, auction_end_price, derived_auction_duration) =
OrderParams::derive_market_order_auction_params(
perp_market,
order.direction,
oracle_price_data.price,
order.price,
)?;

let auction_duration = min_auction_duration;
let auction_duration = auction_duration.max(derived_auction_duration);

let (auction_start_price, auction_end_price) =
calculate_auction_prices(oracle_price_data, order.direction, order.price)?;
Ok((auction_duration, auction_start_price, auction_end_price))
} else {
let (auction_start_price, auction_end_price) =
calculate_auction_prices(oracle_price_data, order.direction, order.price)?;

Ok((auction_duration, auction_start_price, auction_end_price))
Ok((auction_duration, auction_start_price, auction_end_price))
}
}
29 changes: 4 additions & 25 deletions programs/drift/src/math/auction/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,31 +393,6 @@ mod calculate_auction_params_for_trigger_order {
};
let min_auction_duration = 10;

let (auction_duration, auction_start_price, auction_end_price) =
calculate_auction_params_for_trigger_order(
&order,
&oracle_price_data,
min_auction_duration,
)
.unwrap();
assert_eq!(auction_duration, 0);
assert_eq!(auction_start_price, 0);
assert_eq!(auction_end_price, 0);

order.direction = PositionDirection::Short;
order.price = 110 * PRICE_PRECISION_U64;

let (auction_duration, auction_start_price, auction_end_price) =
calculate_auction_params_for_trigger_order(
&order,
&oracle_price_data,
min_auction_duration,
)
.unwrap();
assert_eq!(auction_duration, 0);
assert_eq!(auction_start_price, 0);
assert_eq!(auction_end_price, 0);

order.direction = PositionDirection::Long;
order.price = 110 * PRICE_PRECISION_U64;

Expand All @@ -426,6 +401,7 @@ mod calculate_auction_params_for_trigger_order {
&order,
&oracle_price_data,
min_auction_duration,
None,
)
.unwrap();
assert_eq!(auction_duration, 10);
Expand All @@ -440,6 +416,7 @@ mod calculate_auction_params_for_trigger_order {
&order,
&oracle_price_data,
min_auction_duration,
None,
)
.unwrap();

Expand Down Expand Up @@ -467,6 +444,7 @@ mod calculate_auction_params_for_trigger_order {
&order,
&oracle_price_data,
min_auction_duration,
None,
)
.unwrap();

Expand All @@ -481,6 +459,7 @@ mod calculate_auction_params_for_trigger_order {
&order,
&oracle_price_data,
min_auction_duration,
None,
)
.unwrap();

Expand Down
Loading

0 comments on commit 8fcabd1

Please sign in to comment.