From 035a806a2dc10de12bd3cdbaa7cc135d35687bb5 Mon Sep 17 00:00:00 2001 From: 0xbigz <83473873+0xbigz@users.noreply.github.com> Date: Mon, 19 Jan 2026 11:16:13 -0500 Subject: [PATCH 1/2] feat: convert triggered TriggerLimit orders to Limit orders in modify_order When modifying an order, if the existing order is a TriggerLimit that has already been triggered, it will now be automatically converted to a Limit order. This ensures that once a trigger limit order is triggered, it behaves as a regular limit order with the limit price instead of maintaining trigger-related fields. However, if the user is explicitly trying to modify the trigger price (modify_order_params.trigger_price is Some), the conversion is skipped to handle race conditions where the user updates the trigger price while the order gets triggered. --- programs/drift/src/controller/orders.rs | 48 +++++++++++++++++-------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/programs/drift/src/controller/orders.rs b/programs/drift/src/controller/orders.rs index 1e461a5855..27b78af256 100644 --- a/programs/drift/src/controller/orders.rs +++ b/programs/drift/src/controller/orders.rs @@ -901,7 +901,18 @@ fn merge_modify_order_params_with_existing_order( existing_order: &Order, modify_order_params: &ModifyOrderParams, ) -> DriftResult> { - let order_type = existing_order.order_type; + + // If the order is a trigger limit that has already been triggered, convert it to a limit order + // unless the user is explicitly trying to modify the trigger price (handles race conditions) + let existing_order_triggered = existing_order.order_type == OrderType::TriggerLimit + && existing_order.triggered(); + let user_modifying_trigger_price = modify_order_params.trigger_price.is_some(); + + let order_type = if existing_order_triggered && !user_modifying_trigger_price { + OrderType::Limit + } else { + existing_order.order_type + }; let market_type = existing_order.market_type; let direction = modify_order_params .direction @@ -935,20 +946,27 @@ fn merge_modify_order_params_with_existing_order( }); let bit_flags = 0; let max_ts = modify_order_params.max_ts.or(Some(existing_order.max_ts)); - let trigger_price = modify_order_params - .trigger_price - .or(Some(existing_order.trigger_price)); - let trigger_condition = - modify_order_params - .trigger_condition - .unwrap_or(match existing_order.trigger_condition { - OrderTriggerCondition::TriggeredAbove | OrderTriggerCondition::Above => { - OrderTriggerCondition::Above - } - OrderTriggerCondition::TriggeredBelow | OrderTriggerCondition::Below => { - OrderTriggerCondition::Below - } - }); + // If converting from triggered TriggerLimit to Limit, clear trigger fields + // Only do this if user is not trying to modify trigger price + let (trigger_price, trigger_condition) = if existing_order_triggered && !user_modifying_trigger_price { + (None, OrderTriggerCondition::Above) + } else { + ( + modify_order_params + .trigger_price + .or(Some(existing_order.trigger_price)), + modify_order_params + .trigger_condition + .unwrap_or(match existing_order.trigger_condition { + OrderTriggerCondition::TriggeredAbove | OrderTriggerCondition::Above => { + OrderTriggerCondition::Above + } + OrderTriggerCondition::TriggeredBelow | OrderTriggerCondition::Below => { + OrderTriggerCondition::Below + } + }), + ) + }; let oracle_price_offset = modify_order_params .oracle_price_offset .or(Some(existing_order.oracle_price_offset)); From 995059dbcd5c6d303ab44152cfd8ca5a66fb7a62 Mon Sep 17 00:00:00 2001 From: 0xbigz <83473873+0xbigz@users.noreply.github.com> Date: Mon, 19 Jan 2026 13:31:19 -0500 Subject: [PATCH 2/2] feat: convert triggered TriggerLimit orders to Limit orders in modify_order When modifying an order, if the existing order is a TriggerLimit that has already been triggered, it will now be automatically converted to a Limit order. This ensures that once a trigger limit order is triggered, it behaves as a regular limit order with the limit price instead of maintaining trigger-related fields. However, if the user is explicitly trying to modify the trigger price (modify_order_params.trigger_price is Some), the conversion is skipped to handle race conditions where the user updates the trigger price while the order gets triggered. --- programs/drift/src/controller/orders.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/programs/drift/src/controller/orders.rs b/programs/drift/src/controller/orders.rs index 27b78af256..9544a6b53a 100644 --- a/programs/drift/src/controller/orders.rs +++ b/programs/drift/src/controller/orders.rs @@ -901,9 +901,6 @@ fn merge_modify_order_params_with_existing_order( existing_order: &Order, modify_order_params: &ModifyOrderParams, ) -> DriftResult> { - - // If the order is a trigger limit that has already been triggered, convert it to a limit order - // unless the user is explicitly trying to modify the trigger price (handles race conditions) let existing_order_triggered = existing_order.order_type == OrderType::TriggerLimit && existing_order.triggered(); let user_modifying_trigger_price = modify_order_params.trigger_price.is_some(); @@ -946,8 +943,6 @@ fn merge_modify_order_params_with_existing_order( }); let bit_flags = 0; let max_ts = modify_order_params.max_ts.or(Some(existing_order.max_ts)); - // If converting from triggered TriggerLimit to Limit, clear trigger fields - // Only do this if user is not trying to modify trigger price let (trigger_price, trigger_condition) = if existing_order_triggered && !user_modifying_trigger_price { (None, OrderTriggerCondition::Above) } else { @@ -957,14 +952,7 @@ fn merge_modify_order_params_with_existing_order( .or(Some(existing_order.trigger_price)), modify_order_params .trigger_condition - .unwrap_or(match existing_order.trigger_condition { - OrderTriggerCondition::TriggeredAbove | OrderTriggerCondition::Above => { - OrderTriggerCondition::Above - } - OrderTriggerCondition::TriggeredBelow | OrderTriggerCondition::Below => { - OrderTriggerCondition::Below - } - }), + .unwrap_or(existing_order.trigger_condition), ) }; let oracle_price_offset = modify_order_params