diff --git a/CHANGELOG.md b/CHANGELOG.md index 8db10b947..ad6426c4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- program: stricter logic for atomic fills [#2042](https://github.com/drift-labs/protocol-v2/pull/2042) + ### Fixes ### Breaking diff --git a/programs/drift/src/controller/orders/tests.rs b/programs/drift/src/controller/orders/tests.rs index 5a51991cb..21667d9ef 100644 --- a/programs/drift/src/controller/orders/tests.rs +++ b/programs/drift/src/controller/orders/tests.rs @@ -13075,7 +13075,7 @@ mod order_is_low_risk_for_amm { let mm_oracle_delay = 10i64; let is_low = order - .is_low_risk_for_amm(mm_oracle_delay, clock_slot, false) + .is_low_risk_for_amm(mm_oracle_delay, clock_slot, false, true) .unwrap(); assert!(is_low); } @@ -13088,7 +13088,7 @@ mod order_is_low_risk_for_amm { let mm_oracle_delay = 11i64; let is_low = order - .is_low_risk_for_amm(mm_oracle_delay, clock_slot, false) + .is_low_risk_for_amm(mm_oracle_delay, clock_slot, false, true) .unwrap(); assert!(!is_low); } @@ -13096,7 +13096,9 @@ mod order_is_low_risk_for_amm { #[test] fn liquidation_always_low_risk() { let order = base_perp_order(); - let is_low = order.is_low_risk_for_amm(0, order.slot, true).unwrap(); + let is_low = order + .is_low_risk_for_amm(0, order.slot, true, true) + .unwrap(); assert!(is_low); } @@ -13105,7 +13107,26 @@ mod order_is_low_risk_for_amm { let mut order = base_perp_order(); order.add_bit_flag(OrderBitFlag::SafeTriggerOrder); - let is_low = order.is_low_risk_for_amm(0, order.slot, false).unwrap(); + let is_low = order + .is_low_risk_for_amm(0, order.slot, false, true) + .unwrap(); + assert!(is_low); + } + + #[test] + fn user_can_skip_auction_duration() { + let order = base_perp_order(); + let clock_slot = 110u64; + let mm_oracle_delay = 10i64; + + let is_low = order + .is_low_risk_for_amm(mm_oracle_delay, clock_slot, false, true) + .unwrap(); assert!(is_low); + + let is_low = order + .is_low_risk_for_amm(mm_oracle_delay, clock_slot, false, false) + .unwrap(); + assert!(!is_low); } } diff --git a/programs/drift/src/state/perp_market.rs b/programs/drift/src/state/perp_market.rs index 3d2159366..36e328037 100644 --- a/programs/drift/src/state/perp_market.rs +++ b/programs/drift/src/state/perp_market.rs @@ -948,6 +948,7 @@ impl PerpMarket { safe_oracle_price_data.delay, clock_slot, fill_mode.is_liquidation(), + user_can_skip_auction_duration, )?; // Proceed if order is low risk and we can fill it. Otherwise check if we can higher risk order immediately diff --git a/programs/drift/src/state/user.rs b/programs/drift/src/state/user.rs index a89467cce..017f5aeb2 100644 --- a/programs/drift/src/state/user.rs +++ b/programs/drift/src/state/user.rs @@ -1531,6 +1531,7 @@ impl Order { mm_oracle_delay: i64, clock_slot: u64, is_liquidation: bool, + user_can_skip_auction_duration: bool, ) -> DriftResult { if self.market_type == MarketType::Spot { return Ok(false); @@ -1538,7 +1539,11 @@ impl Order { let order_older_than_oracle_delay = { let clock_minus_delay = clock_slot.cast::()?.safe_sub(mm_oracle_delay)?; - clock_minus_delay >= self.slot.cast::()? + if user_can_skip_auction_duration { + clock_minus_delay >= self.slot.cast::()? + } else { + clock_minus_delay > self.slot.cast::()? + } }; Ok(order_older_than_oracle_delay