@@ -2,7 +2,7 @@ use std::{
22 collections:: HashSet ,
33 env,
44 net:: SocketAddr ,
5- sync:: { atomic:: AtomicBool , Arc } ,
5+ sync:: { atomic:: AtomicBool , Arc , LazyLock } ,
66 time:: { Duration , SystemTime } ,
77} ;
88
@@ -370,6 +370,20 @@ pub async fn send_heartbeat(server_params: &'static ServerParams) {
370370 }
371371}
372372
373+ static DEPOSIT_IX_WHITELIST : LazyLock < HashSet < [ u8 ; 8 ] > > = LazyLock :: new ( || {
374+ HashSet :: < [ u8 ; 8 ] > :: from_iter ( [
375+ drift_idl:: instructions:: Deposit :: DISCRIMINATOR
376+ . try_into ( )
377+ . unwrap ( ) ,
378+ drift_idl:: instructions:: EnableUserHighLeverageMode :: DISCRIMINATOR
379+ . try_into ( )
380+ . unwrap ( ) ,
381+ drift_idl:: instructions:: InitializeSignedMsgUserOrders :: DISCRIMINATOR
382+ . try_into ( )
383+ . unwrap ( ) ,
384+ ] )
385+ } ) ;
386+
373387pub async fn deposit_trade (
374388 State ( server_params) : State < & ' static ServerParams > ,
375389 Json ( req) : Json < DepositAndPlaceRequest > ,
@@ -390,38 +404,56 @@ pub async fn deposit_trade(
390404 }
391405
392406 // verify deposit ix exists and amount
393- let ix = & req. deposit_tx . message . instructions ( ) [ 0 ] ;
394- if & ix. data [ ..8 ] == drift_idl:: instructions:: Deposit :: DISCRIMINATOR {
395- if let Ok ( deposit_ix) = drift_idl:: instructions:: Deposit :: deserialize ( & mut & ix. data [ 8 ..] ) {
396- let spot_oracle = server_params
397- . drift
398- . try_get_oracle_price_data_and_slot ( MarketId :: spot ( deposit_ix. market_index ) )
399- . expect ( "got price" ) ;
400- let deposit_value = spot_oracle. data . price as u64 * deposit_ix. amount ;
401- if deposit_value < min_deposit_value {
407+ let mut has_deposit = false ;
408+ for ix in req. deposit_tx . message . instructions ( ) {
409+ let ix_disc = & ix. data [ ..8 ] ;
410+ if !DEPOSIT_IX_WHITELIST . contains ( ix_disc) {
411+ return (
412+ StatusCode :: BAD_REQUEST ,
413+ Json ( ProcessOrderResponse {
414+ message : "" ,
415+ error : Some ( "unsupported deposit ix" . into ( ) ) ,
416+ } ) ,
417+ ) ;
418+ }
419+
420+ if ix_disc == drift_idl:: instructions:: Deposit :: DISCRIMINATOR {
421+ has_deposit = true ;
422+ if let Ok ( deposit_ix) =
423+ drift_idl:: instructions:: Deposit :: deserialize ( & mut & ix. data [ 8 ..] )
424+ {
425+ let spot_oracle = server_params
426+ . drift
427+ . try_get_oracle_price_data_and_slot ( MarketId :: spot ( deposit_ix. market_index ) )
428+ . expect ( "got price" ) ;
429+ let deposit_value = spot_oracle. data . price as u64 * deposit_ix. amount ;
430+ if deposit_value < min_deposit_value {
431+ return (
432+ StatusCode :: BAD_REQUEST ,
433+ Json ( ProcessOrderResponse {
434+ message : "" ,
435+ error : Some ( format ! ( "deposit value must be > ${min_deposit_value}" ) ) ,
436+ } ) ,
437+ ) ;
438+ }
439+ } else {
402440 return (
403441 StatusCode :: BAD_REQUEST ,
404442 Json ( ProcessOrderResponse {
405443 message : "" ,
406- error : Some ( format ! ( " deposit size must be > ${min_deposit_value}" ) ) ,
444+ error : Some ( "invalid deposit ix encoding" . into ( ) ) ,
407445 } ) ,
408446 ) ;
409447 }
410- } else {
411- return (
412- StatusCode :: BAD_REQUEST ,
413- Json ( ProcessOrderResponse {
414- message : "" ,
415- error : Some ( "invalid deposit ix encoding" . into ( ) ) ,
416- } ) ,
417- ) ;
418448 }
419- } else {
449+ }
450+
451+ if !has_deposit {
420452 return (
421453 StatusCode :: BAD_REQUEST ,
422454 Json ( ProcessOrderResponse {
423455 message : "" ,
424- error : Some ( "invalid deposit ix" . into ( ) ) ,
456+ error : Some ( "missing deposit ix" . into ( ) ) ,
425457 } ) ,
426458 ) ;
427459 }
0 commit comments