@@ -10397,6 +10397,228 @@ pub mod force_cancel_orders {
1039710397 }
1039810398}
1039910399
10400+ pub mod cancel_reduce_only_trigger_orders {
10401+ use std:: str:: FromStr ;
10402+
10403+ use anchor_lang:: prelude:: Clock ;
10404+
10405+ use crate :: controller:: orders:: cancel_reduce_only_trigger_orders;
10406+ use crate :: controller:: position:: PositionDirection ;
10407+ use crate :: create_account_info;
10408+ use crate :: create_anchor_account_info;
10409+ use crate :: math:: constants:: {
10410+ AMM_RESERVE_PRECISION , BASE_PRECISION_I64 , LAMPORTS_PER_SOL_I64 , PEG_PRECISION ,
10411+ SPOT_BALANCE_PRECISION , SPOT_BALANCE_PRECISION_U64 , SPOT_CUMULATIVE_INTEREST_PRECISION ,
10412+ SPOT_WEIGHT_PRECISION ,
10413+ } ;
10414+ use crate :: state:: oracle:: HistoricalOracleData ;
10415+ use crate :: state:: oracle:: OracleSource ;
10416+ use crate :: state:: perp_market:: { PerpMarket , AMM } ;
10417+ use crate :: state:: perp_market_map:: PerpMarketMap ;
10418+ use crate :: state:: spot_market:: { SpotBalanceType , SpotMarket } ;
10419+ use crate :: state:: spot_market_map:: SpotMarketMap ;
10420+ use crate :: state:: state:: State ;
10421+ use crate :: state:: user:: { MarketType , OrderStatus , OrderType , SpotPosition , User } ;
10422+ use crate :: test_utils:: * ;
10423+ use crate :: test_utils:: {
10424+ create_account_info, get_positions, get_pyth_price, get_spot_positions,
10425+ } ;
10426+
10427+ use super :: * ;
10428+
10429+ #[ test]
10430+ fn test ( ) {
10431+ let clock = Clock {
10432+ slot : 6 ,
10433+ epoch_start_timestamp : 0 ,
10434+ epoch : 0 ,
10435+ leader_schedule_epoch : 0 ,
10436+ unix_timestamp : 0 ,
10437+ } ;
10438+
10439+ let mut oracle_price = get_pyth_price ( 100 , 6 ) ;
10440+ let oracle_price_key =
10441+ Pubkey :: from_str ( "J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix" ) . unwrap ( ) ;
10442+ let pyth_program = crate :: ids:: pyth_program:: id ( ) ;
10443+ create_account_info ! (
10444+ oracle_price,
10445+ & oracle_price_key,
10446+ & pyth_program,
10447+ oracle_account_info
10448+ ) ;
10449+ let mut oracle_map = OracleMap :: load_one ( & oracle_account_info, clock. slot , None ) . unwrap ( ) ;
10450+
10451+ let mut market = PerpMarket {
10452+ amm : AMM {
10453+ base_asset_reserve : 100 * AMM_RESERVE_PRECISION ,
10454+ quote_asset_reserve : 100 * AMM_RESERVE_PRECISION ,
10455+ terminal_quote_asset_reserve : 100 * AMM_RESERVE_PRECISION ,
10456+ // bid_base_asset_reserve: 101 * AMM_RESERVE_PRECISION,
10457+ // bid_quote_asset_reserve: 99 * AMM_RESERVE_PRECISION,
10458+ // ask_base_asset_reserve: 99 * AMM_RESERVE_PRECISION,
10459+ // ask_quote_asset_reserve: 101 * AMM_RESERVE_PRECISION,
10460+ sqrt_k : 100 * AMM_RESERVE_PRECISION ,
10461+ peg_multiplier : 100 * PEG_PRECISION ,
10462+ max_slippage_ratio : 100 ,
10463+ max_fill_reserve_fraction : 100 ,
10464+ order_step_size : 1000 ,
10465+ order_tick_size : 1 ,
10466+ oracle : oracle_price_key,
10467+ max_spread : 1000 ,
10468+ base_spread : 0 ,
10469+ long_spread : 0 ,
10470+ short_spread : 0 ,
10471+ historical_oracle_data : HistoricalOracleData {
10472+ last_oracle_price_twap : oracle_price. twap ,
10473+ last_oracle_price_twap_5min : oracle_price. twap ,
10474+ last_oracle_price : oracle_price. agg . price ,
10475+ ..HistoricalOracleData :: default ( )
10476+ } ,
10477+ ..AMM :: default ( )
10478+ } ,
10479+ margin_ratio_initial : 1000 ,
10480+ margin_ratio_maintenance : 500 ,
10481+ status : MarketStatus :: Initialized ,
10482+ ..PerpMarket :: default ( )
10483+ } ;
10484+ market. status = MarketStatus :: Active ;
10485+ market. amm . max_base_asset_reserve = u128:: MAX ;
10486+ market. amm . min_base_asset_reserve = 0 ;
10487+ let ( new_ask_base_asset_reserve, new_ask_quote_asset_reserve) =
10488+ crate :: math:: amm_spread:: calculate_spread_reserves ( & market, PositionDirection :: Long )
10489+ . unwrap ( ) ;
10490+ let ( new_bid_base_asset_reserve, new_bid_quote_asset_reserve) =
10491+ crate :: math:: amm_spread:: calculate_spread_reserves ( & market, PositionDirection :: Short )
10492+ . unwrap ( ) ;
10493+ market. amm . ask_base_asset_reserve = new_ask_base_asset_reserve;
10494+ market. amm . bid_base_asset_reserve = new_bid_base_asset_reserve;
10495+ market. amm . ask_quote_asset_reserve = new_ask_quote_asset_reserve;
10496+ market. amm . bid_quote_asset_reserve = new_bid_quote_asset_reserve;
10497+ create_anchor_account_info ! ( market, PerpMarket , market_account_info) ;
10498+ let market_map = PerpMarketMap :: load_one ( & market_account_info, true ) . unwrap ( ) ;
10499+
10500+ let mut usdc_spot_market = SpotMarket {
10501+ market_index : 0 ,
10502+ oracle_source : OracleSource :: QuoteAsset ,
10503+ deposit_balance : SPOT_BALANCE_PRECISION ,
10504+ cumulative_deposit_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10505+ cumulative_borrow_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10506+ decimals : 6 ,
10507+ initial_asset_weight : SPOT_WEIGHT_PRECISION ,
10508+ maintenance_asset_weight : SPOT_WEIGHT_PRECISION ,
10509+ ..SpotMarket :: default ( )
10510+ } ;
10511+ create_anchor_account_info ! ( usdc_spot_market, SpotMarket , usdc_spot_market_account_info) ;
10512+
10513+ let mut sol_spot_market = SpotMarket {
10514+ market_index : 1 ,
10515+ deposit_balance : SPOT_BALANCE_PRECISION ,
10516+ cumulative_deposit_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10517+ cumulative_borrow_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10518+ oracle : oracle_price_key,
10519+ ..SpotMarket :: default_base_market ( )
10520+ } ;
10521+ create_anchor_account_info ! ( sol_spot_market, SpotMarket , sol_spot_market_account_info) ;
10522+
10523+ let spot_market_map = SpotMarketMap :: load_multiple (
10524+ vec ! [
10525+ & usdc_spot_market_account_info,
10526+ & sol_spot_market_account_info,
10527+ ] ,
10528+ true ,
10529+ )
10530+ . unwrap ( ) ;
10531+
10532+ let mut orders = [ Order :: default ( ) ; 32 ] ;
10533+ orders[ 0 ] = Order {
10534+ market_index : 0 ,
10535+ order_id : 1 ,
10536+ status : OrderStatus :: Open ,
10537+ order_type : OrderType :: Limit ,
10538+ market_type : MarketType :: Perp ,
10539+ ..Order :: default ( )
10540+ } ;
10541+ orders[ 1 ] = Order {
10542+ market_index : 1 ,
10543+ order_id : 2 ,
10544+ status : OrderStatus :: Open ,
10545+ order_type : OrderType :: TriggerMarket ,
10546+ market_type : MarketType :: Perp ,
10547+ reduce_only : true ,
10548+ ..Order :: default ( )
10549+ } ;
10550+ orders[ 2 ] = Order {
10551+ market_index : 0 ,
10552+ order_id : 2 ,
10553+ status : OrderStatus :: Open ,
10554+ order_type : OrderType :: TriggerMarket ,
10555+ market_type : MarketType :: Perp ,
10556+ reduce_only : true ,
10557+ ..Order :: default ( )
10558+ } ;
10559+ orders[ 3 ] = Order {
10560+ market_index : 0 ,
10561+ order_id : 2 ,
10562+ status : OrderStatus :: Open ,
10563+ order_type : OrderType :: TriggerMarket ,
10564+ market_type : MarketType :: Spot ,
10565+ reduce_only : true ,
10566+ ..Order :: default ( )
10567+ } ;
10568+ orders[ 4 ] = Order {
10569+ market_index : 0 ,
10570+ order_id : 2 ,
10571+ status : OrderStatus :: Open ,
10572+ order_type : OrderType :: TriggerLimit ,
10573+ market_type : MarketType :: Perp ,
10574+ reduce_only : true ,
10575+ ..Order :: default ( )
10576+ } ;
10577+
10578+ let mut user = User {
10579+ authority : Pubkey :: from_str ( "My11111111111111111111111111111111111111111" ) . unwrap ( ) , // different authority than filler
10580+ orders,
10581+ perp_positions : get_positions ( PerpPosition {
10582+ market_index : 0 ,
10583+ base_asset_amount : BASE_PRECISION_I64 ,
10584+ open_orders : 2 ,
10585+ open_bids : 100 * BASE_PRECISION_I64 ,
10586+ open_asks : -BASE_PRECISION_I64 ,
10587+ ..PerpPosition :: default ( )
10588+ } ) ,
10589+ spot_positions : get_spot_positions ( SpotPosition {
10590+ market_index : 1 ,
10591+ balance_type : SpotBalanceType :: Deposit ,
10592+ scaled_balance : SPOT_BALANCE_PRECISION_U64 ,
10593+ open_orders : 2 ,
10594+ open_bids : 100 * LAMPORTS_PER_SOL_I64 ,
10595+ open_asks : -LAMPORTS_PER_SOL_I64 ,
10596+ ..SpotPosition :: default ( )
10597+ } ) ,
10598+ ..User :: default ( )
10599+ } ;
10600+
10601+ cancel_reduce_only_trigger_orders (
10602+ & mut user,
10603+ & Pubkey :: default ( ) ,
10604+ Some ( & Pubkey :: default ( ) ) ,
10605+ & market_map,
10606+ & spot_market_map,
10607+ & mut oracle_map,
10608+ 0 ,
10609+ 0 ,
10610+ 0 ,
10611+ )
10612+ . unwrap ( ) ;
10613+
10614+ assert_eq ! ( user. orders[ 0 ] . status, OrderStatus :: Open ) ;
10615+ assert_eq ! ( user. orders[ 1 ] . status, OrderStatus :: Open ) ;
10616+ assert_eq ! ( user. orders[ 2 ] . status, OrderStatus :: Canceled ) ;
10617+ assert_eq ! ( user. orders[ 3 ] . status, OrderStatus :: Open ) ;
10618+ assert_eq ! ( user. orders[ 4 ] . status, OrderStatus :: Canceled ) ;
10619+ }
10620+ }
10621+
1040010622pub mod insert_maker_order_info {
1040110623 use crate :: controller:: orders:: insert_maker_order_info;
1040210624 use crate :: controller:: position:: PositionDirection ;
0 commit comments