@@ -239,6 +239,7 @@ pub async fn process_order(
239239 uuid,
240240 } ,
241241 max_margin_ratio,
242+ is_isolated_deposit,
242243 ) = extract_signed_message_info ( signed_msg, & taker_authority, current_slot) ?;
243244
244245 log:: info!(
@@ -301,6 +302,7 @@ pub async fn process_order(
301302 delegate_signer,
302303 current_slot,
303304 max_margin_ratio,
305+ is_isolated_deposit,
304306 context,
305307 )
306308 . await
@@ -443,7 +445,7 @@ pub async fn deposit_trade(
443445 & req. swift_order . taker_authority ,
444446 current_slot,
445447 ) {
446- Ok ( ( _info, max_margin_ratio) ) => max_margin_ratio,
448+ Ok ( ( _info, max_margin_ratio, _is_isolated ) ) => max_margin_ratio,
447449 Err ( ( _status, err) ) => return ( StatusCode :: BAD_REQUEST , Json ( err) ) ,
448450 } ;
449451
@@ -1058,6 +1060,7 @@ impl ServerParams {
10581060 delegate_signer : Option < & Pubkey > ,
10591061 slot : Slot ,
10601062 max_margin_ratio : Option < u16 > ,
1063+ is_isolated_deposit : bool ,
10611064 context : & RequestContext ,
10621065 ) -> Result < SimulationStatus , ( axum:: http:: StatusCode , String , Option < Vec < String > > ) > {
10631066 let mut sim_result = SimulationStatus :: Disabled ;
@@ -1189,7 +1192,10 @@ impl ServerParams {
11891192 match err. to_anchor_error_code ( ) {
11901193 Some ( code) => {
11911194 // insufficient collateral is prone to precision errors, allow the order through with some leniency
1192- if code == ProgramError :: Drift ( ErrorCode :: InsufficientCollateral ) {
1195+ // EXCEPT for isolated deposits, where we want to return the error to the client
1196+ if code == ProgramError :: Drift ( ErrorCode :: InsufficientCollateral )
1197+ && !is_isolated_deposit
1198+ {
11931199 if let Some ( ref logs) = res. value . logs {
11941200 if let Some ( collateral_ratio) = extract_collateral_ratio ( logs) {
11951201 if collateral_ratio <= COLLATERAL_BUFFER {
@@ -1518,11 +1524,24 @@ fn validate_order(
15181524 Ok ( ( ) )
15191525}
15201526
1527+ fn is_isolated_deposit ( signed_msg : & SignedOrderType ) -> bool {
1528+ match signed_msg {
1529+ SignedOrderType :: Delegated { inner, .. } => inner
1530+ . isolated_position_deposit
1531+ . is_some_and ( |amount| amount > 0 ) ,
1532+ SignedOrderType :: Authority { inner, .. } => inner
1533+ . isolated_position_deposit
1534+ . is_some_and ( |amount| amount > 0 ) ,
1535+ }
1536+ }
1537+
15211538fn extract_signed_message_info (
15221539 signed_msg : & SignedOrderType ,
15231540 taker_authority : & Pubkey ,
15241541 current_slot : Slot ,
1525- ) -> Result < ( SignedMessageInfo , Option < u16 > ) , ( axum:: http:: StatusCode , ProcessOrderResponse ) > {
1542+ ) -> Result < ( SignedMessageInfo , Option < u16 > , bool ) , ( axum:: http:: StatusCode , ProcessOrderResponse ) >
1543+ {
1544+ let is_isolated = is_isolated_deposit ( signed_msg) ;
15261545 match signed_msg {
15271546 SignedOrderType :: Delegated { inner, .. } => {
15281547 validate_order (
@@ -1539,6 +1558,7 @@ fn extract_signed_message_info(
15391558 slot : inner. slot ,
15401559 } ,
15411560 inner. max_margin_ratio ,
1561+ is_isolated,
15421562 ) )
15431563 }
15441564 SignedOrderType :: Authority { inner, .. } => {
@@ -1559,6 +1579,7 @@ fn extract_signed_message_info(
15591579 slot : inner. slot ,
15601580 } ,
15611581 inner. max_margin_ratio ,
1582+ is_isolated,
15621583 ) )
15631584 }
15641585 }
@@ -1872,7 +1893,7 @@ mod tests {
18721893 } ) ;
18731894
18741895 let result = extract_signed_message_info ( & delegated_msg, & taker_authority, current_slot) ;
1875- assert ! ( result. is_ok_and( |( info, _) | {
1896+ assert ! ( result. is_ok_and( |( info, _, _ ) | {
18761897 info. slot == current_slot
18771898 && info. order_params. base_asset_amount == LAMPORTS_PER_SOL
18781899 && info. order_params. order_type == OrderType :: Market
@@ -1940,7 +1961,7 @@ mod tests {
19401961 } ) ;
19411962
19421963 let result = extract_signed_message_info ( & authority_msg, & taker_authority, current_slot) ;
1943- assert ! ( result. is_ok_and( |( info, _margin_ratio) | {
1964+ assert ! ( result. is_ok_and( |( info, _margin_ratio, _is_isolated ) | {
19441965 info. slot == current_slot
19451966 && info. order_params. base_asset_amount == LAMPORTS_PER_SOL
19461967 && info. order_params. order_type == OrderType :: Market
@@ -2019,6 +2040,137 @@ mod tests {
20192040 ) ) ) ;
20202041 }
20212042
2043+ #[ test]
2044+ fn test_is_isolated_deposit ( ) {
2045+ let taker_authority = Pubkey :: new_unique ( ) ;
2046+ let current_slot = 1000 ;
2047+
2048+ // Test delegated order with no isolated deposit
2049+ let delegated_msg = SignedOrderType :: delegated ( SignedMsgOrderParamsDelegateMessage {
2050+ taker_pubkey : Pubkey :: new_unique ( ) ,
2051+ signed_msg_order_params : OrderParams {
2052+ market_index : 0 ,
2053+ market_type : MarketType :: Perp ,
2054+ order_type : OrderType :: Market ,
2055+ base_asset_amount : LAMPORTS_PER_SOL ,
2056+ price : 1000 ,
2057+ direction : PositionDirection :: Long ,
2058+ ..Default :: default ( )
2059+ } ,
2060+ uuid : [ 1 ; 8 ] ,
2061+ slot : current_slot,
2062+ stop_loss_order_params : None ,
2063+ take_profit_order_params : None ,
2064+ max_margin_ratio : None ,
2065+ builder_fee_tenth_bps : None ,
2066+ builder_idx : None ,
2067+ isolated_position_deposit : None ,
2068+ } ) ;
2069+ assert ! ( !is_isolated_deposit( & delegated_msg) ) ;
2070+ let result = extract_signed_message_info ( & delegated_msg, & taker_authority, current_slot) ;
2071+ assert ! ( result. is_ok_and( |( _, _, is_isolated) | !is_isolated) ) ;
2072+
2073+ // Test delegated order with isolated deposit of 0 (should be false)
2074+ let delegated_msg = SignedOrderType :: delegated ( SignedMsgOrderParamsDelegateMessage {
2075+ taker_pubkey : Pubkey :: new_unique ( ) ,
2076+ signed_msg_order_params : OrderParams {
2077+ market_index : 0 ,
2078+ market_type : MarketType :: Perp ,
2079+ order_type : OrderType :: Market ,
2080+ base_asset_amount : LAMPORTS_PER_SOL ,
2081+ price : 1000 ,
2082+ direction : PositionDirection :: Long ,
2083+ ..Default :: default ( )
2084+ } ,
2085+ uuid : [ 1 ; 8 ] ,
2086+ slot : current_slot,
2087+ stop_loss_order_params : None ,
2088+ take_profit_order_params : None ,
2089+ max_margin_ratio : None ,
2090+ builder_fee_tenth_bps : None ,
2091+ builder_idx : None ,
2092+ isolated_position_deposit : Some ( 0 ) ,
2093+ } ) ;
2094+ assert ! ( !is_isolated_deposit( & delegated_msg) ) ;
2095+ let result = extract_signed_message_info ( & delegated_msg, & taker_authority, current_slot) ;
2096+ assert ! ( result. is_ok_and( |( _, _, is_isolated) | !is_isolated) ) ;
2097+
2098+ // Test delegated order with isolated deposit > 0
2099+ let delegated_msg = SignedOrderType :: delegated ( SignedMsgOrderParamsDelegateMessage {
2100+ taker_pubkey : Pubkey :: new_unique ( ) ,
2101+ signed_msg_order_params : OrderParams {
2102+ market_index : 0 ,
2103+ market_type : MarketType :: Perp ,
2104+ order_type : OrderType :: Market ,
2105+ base_asset_amount : LAMPORTS_PER_SOL ,
2106+ price : 1000 ,
2107+ direction : PositionDirection :: Long ,
2108+ ..Default :: default ( )
2109+ } ,
2110+ uuid : [ 1 ; 8 ] ,
2111+ slot : current_slot,
2112+ stop_loss_order_params : None ,
2113+ take_profit_order_params : None ,
2114+ max_margin_ratio : None ,
2115+ builder_fee_tenth_bps : None ,
2116+ builder_idx : None ,
2117+ isolated_position_deposit : Some ( 100_000_000 ) , // 0.1 SOL
2118+ } ) ;
2119+ assert ! ( is_isolated_deposit( & delegated_msg) ) ;
2120+ let result = extract_signed_message_info ( & delegated_msg, & taker_authority, current_slot) ;
2121+ assert ! ( result. is_ok_and( |( _, _, is_isolated) | is_isolated) ) ;
2122+
2123+ // Test authority order with no isolated deposit
2124+ let authority_msg = SignedOrderType :: authority ( SignedMsgOrderParamsMessage {
2125+ sub_account_id : 0 ,
2126+ signed_msg_order_params : OrderParams {
2127+ market_index : 0 ,
2128+ market_type : MarketType :: Perp ,
2129+ order_type : OrderType :: Market ,
2130+ base_asset_amount : LAMPORTS_PER_SOL ,
2131+ price : 1000 ,
2132+ direction : PositionDirection :: Long ,
2133+ ..Default :: default ( )
2134+ } ,
2135+ uuid : [ 1 ; 8 ] ,
2136+ slot : current_slot,
2137+ stop_loss_order_params : None ,
2138+ take_profit_order_params : None ,
2139+ max_margin_ratio : None ,
2140+ builder_fee_tenth_bps : None ,
2141+ builder_idx : None ,
2142+ isolated_position_deposit : None ,
2143+ } ) ;
2144+ assert ! ( !is_isolated_deposit( & authority_msg) ) ;
2145+ let result = extract_signed_message_info ( & authority_msg, & taker_authority, current_slot) ;
2146+ assert ! ( result. is_ok_and( |( _, _, is_isolated) | !is_isolated) ) ;
2147+
2148+ // Test authority order with isolated deposit > 0
2149+ let authority_msg = SignedOrderType :: authority ( SignedMsgOrderParamsMessage {
2150+ sub_account_id : 0 ,
2151+ signed_msg_order_params : OrderParams {
2152+ market_index : 0 ,
2153+ market_type : MarketType :: Perp ,
2154+ order_type : OrderType :: Market ,
2155+ base_asset_amount : LAMPORTS_PER_SOL ,
2156+ price : 1000 ,
2157+ direction : PositionDirection :: Long ,
2158+ ..Default :: default ( )
2159+ } ,
2160+ uuid : [ 1 ; 8 ] ,
2161+ slot : current_slot,
2162+ stop_loss_order_params : None ,
2163+ take_profit_order_params : None ,
2164+ max_margin_ratio : None ,
2165+ builder_fee_tenth_bps : None ,
2166+ builder_idx : None ,
2167+ isolated_position_deposit : Some ( 50_000_000 ) , // 0.05 SOL
2168+ } ) ;
2169+ assert ! ( is_isolated_deposit( & authority_msg) ) ;
2170+ let result = extract_signed_message_info ( & authority_msg, & taker_authority, current_slot) ;
2171+ assert ! ( result. is_ok_and( |( _, _, is_isolated) | is_isolated) ) ;
2172+ }
2173+
20222174 #[ tokio:: test]
20232175 async fn test_simulate_taker_order_rpc ( ) {
20242176 let _ = env_logger:: try_init ( ) ;
@@ -2096,6 +2248,7 @@ mod tests {
20962248 Some ( & delegate_pubkey) ,
20972249 1_000 ,
20982250 None ,
2251+ false ,
20992252 & context_primary,
21002253 )
21012254 . await ;
@@ -2121,6 +2274,7 @@ mod tests {
21212274 Some ( & delegate_pubkey) ,
21222275 1_000 ,
21232276 None ,
2277+ false ,
21242278 & context_secondary,
21252279 )
21262280 . await ;
0 commit comments