diff --git a/CHANGELOG.md b/CHANGELOG.md index d456a1f41..350ed86f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixes +- program: make ModifyOrderParams a bit flag and add ExcludePreviousFill ([#1357](https://github.com/drift-labs/protocol-v2/pull/1357)) + - program: fix force delete user for token 2022 ([#1358](https://github.com/drift-labs/protocol-v2/pull/1358)) ### Breaking diff --git a/programs/drift/src/controller/orders.rs b/programs/drift/src/controller/orders.rs index ed37e294f..93959f80b 100644 --- a/programs/drift/src/controller/orders.rs +++ b/programs/drift/src/controller/orders.rs @@ -904,7 +904,7 @@ pub fn modify_order( Ok(order_index) => order_index, Err(e) => { msg!("User order id {} not found", user_order_id); - if modify_order_params.policy == Some(ModifyOrderPolicy::MustModify) { + if modify_order_params.must_modify() { return Err(e); } else { return Ok(()); @@ -916,7 +916,7 @@ pub fn modify_order( Ok(order_index) => order_index, Err(e) => { msg!("Order id {} not found", order_id); - if modify_order_params.policy == Some(ModifyOrderPolicy::MustModify) { + if modify_order_params.must_modify() { return Err(e); } else { return Ok(()); @@ -947,30 +947,32 @@ pub fn modify_order( let order_params = merge_modify_order_params_with_existing_order(&existing_order, &modify_order_params)?; - if order_params.market_type == MarketType::Perp { - place_perp_order( - state, - &mut user, - user_key, - perp_market_map, - spot_market_map, - oracle_map, - clock, - order_params, - PlaceOrderOptions::default(), - )?; - } else { - place_spot_order( - state, - &mut user, - user_key, - perp_market_map, - spot_market_map, - oracle_map, - clock, - order_params, - PlaceOrderOptions::default(), - )?; + if let Some(order_params) = order_params { + if order_params.market_type == MarketType::Perp { + place_perp_order( + state, + &mut user, + user_key, + perp_market_map, + spot_market_map, + oracle_map, + clock, + order_params, + PlaceOrderOptions::default(), + )?; + } else { + place_spot_order( + state, + &mut user, + user_key, + perp_market_map, + spot_market_map, + oracle_map, + clock, + order_params, + PlaceOrderOptions::default(), + )?; + } } Ok(()) @@ -979,16 +981,27 @@ pub fn modify_order( fn merge_modify_order_params_with_existing_order( existing_order: &Order, modify_order_params: &ModifyOrderParams, -) -> DriftResult { +) -> DriftResult> { let order_type = existing_order.order_type; let market_type = existing_order.market_type; let direction = modify_order_params .direction .unwrap_or(existing_order.direction); let user_order_id = existing_order.user_order_id; - let base_asset_amount = modify_order_params - .base_asset_amount - .unwrap_or(existing_order.get_base_asset_amount_unfilled(None)?); + let base_asset_amount = match modify_order_params.base_asset_amount { + Some(base_asset_amount) if modify_order_params.exclude_previous_fill() => { + let base_asset_amount = + base_asset_amount.saturating_sub(existing_order.base_asset_amount_filled); + + if base_asset_amount == 0 { + return Ok(None); + } + + base_asset_amount + } + Some(base_asset_amount) => base_asset_amount, + None => existing_order.get_base_asset_amount_unfilled(None)?, + }; let price = modify_order_params.price.unwrap_or(existing_order.price); let market_index = existing_order.market_index; let reduce_only = modify_order_params @@ -1034,7 +1047,7 @@ fn merge_modify_order_params_with_existing_order( (None, None, None) }; - Ok(OrderParams { + Ok(Some(OrderParams { order_type, market_type, direction, @@ -1052,7 +1065,7 @@ fn merge_modify_order_params_with_existing_order( auction_duration, auction_start_price, auction_end_price, - }) + })) } pub fn fill_perp_order( diff --git a/programs/drift/src/state/order_params.rs b/programs/drift/src/state/order_params.rs index 12e4a6dd1..1564ed800 100644 --- a/programs/drift/src/state/order_params.rs +++ b/programs/drift/src/state/order_params.rs @@ -796,20 +796,24 @@ pub struct ModifyOrderParams { pub auction_duration: Option, pub auction_start_price: Option, pub auction_end_price: Option, - pub policy: Option, + pub policy: Option, } -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Eq, PartialEq)] -pub enum ModifyOrderPolicy { - TryModify, - MustModify, -} +impl ModifyOrderParams { + pub fn must_modify(&self) -> bool { + self.policy.unwrap_or(0) & ModifyOrderPolicy::MustModify as u8 != 0 + } -impl Default for ModifyOrderPolicy { - fn default() -> Self { - Self::TryModify + pub fn exclude_previous_fill(&self) -> bool { + self.policy.unwrap_or(0) & ModifyOrderPolicy::ExcludePreviousFill as u8 != 0 } } + +pub enum ModifyOrderPolicy { + MustModify = 1, + ExcludePreviousFill = 2, +} + #[derive(Clone)] pub struct PlaceOrderOptions { pub swift_taker_order_slot: Option, diff --git a/sdk/src/driftClient.ts b/sdk/src/driftClient.ts index 69a7519fd..cf67b1406 100644 --- a/sdk/src/driftClient.ts +++ b/sdk/src/driftClient.ts @@ -6477,7 +6477,7 @@ export class DriftClient { postOnly?: boolean; immediateOrCancel?: boolean; maxTs?: BN; - policy?: ModifyOrderPolicy; + policy?: number; }, txParams?: TxParams, subAccountId?: number @@ -6525,7 +6525,7 @@ export class DriftClient { postOnly?: boolean; immediateOrCancel?: boolean; maxTs?: BN; - policy?: ModifyOrderPolicy; + policy?: number; }, subAccountId?: number ): Promise { diff --git a/sdk/src/types.ts b/sdk/src/types.ts index f8a6e668e..23a279c94 100644 --- a/sdk/src/types.ts +++ b/sdk/src/types.ts @@ -1077,9 +1077,9 @@ export type ModifyOrderParams = { [Property in keyof OrderParams]?: OrderParams[Property] | null; } & { policy?: ModifyOrderPolicy }; -export class ModifyOrderPolicy { - static readonly MUST_MODIFY = { mustModify: {} }; - static readonly TRY_MODIFY = { tryModify: {} }; +export enum ModifyOrderPolicy { + MustModify = 1, + ExcludePreviousFill = 2, } export const DefaultOrderParams: OrderParams = {