@@ -10315,6 +10315,229 @@ pub mod force_cancel_orders {
1031510315 }
1031610316}
1031710317
10318+ pub mod cancel_reduce_only_trigger_orders {
10319+ use std:: str:: FromStr ;
10320+
10321+ use anchor_lang:: prelude:: Clock ;
10322+
10323+ use crate :: controller:: orders:: cancel_reduce_only_trigger_orders;
10324+ use crate :: controller:: position:: PositionDirection ;
10325+ use crate :: create_account_info;
10326+ use crate :: create_anchor_account_info;
10327+ use crate :: math:: constants:: {
10328+ AMM_RESERVE_PRECISION , BASE_PRECISION_I64 , LAMPORTS_PER_SOL_I64 ,
10329+ PEG_PRECISION , SPOT_BALANCE_PRECISION ,
10330+ SPOT_BALANCE_PRECISION_U64 , SPOT_CUMULATIVE_INTEREST_PRECISION , SPOT_WEIGHT_PRECISION ,
10331+ } ;
10332+ use crate :: state:: oracle:: HistoricalOracleData ;
10333+ use crate :: state:: oracle:: OracleSource ;
10334+ use crate :: state:: perp_market:: { PerpMarket , AMM } ;
10335+ use crate :: state:: perp_market_map:: PerpMarketMap ;
10336+ use crate :: state:: spot_market:: { SpotBalanceType , SpotMarket } ;
10337+ use crate :: state:: spot_market_map:: SpotMarketMap ;
10338+ use crate :: state:: state:: State ;
10339+ use crate :: state:: user:: { MarketType , OrderStatus , OrderType , SpotPosition , User } ;
10340+ use crate :: test_utils:: * ;
10341+ use crate :: test_utils:: {
10342+ create_account_info, get_positions, get_pyth_price, get_spot_positions,
10343+ } ;
10344+
10345+ use super :: * ;
10346+
10347+ #[ test]
10348+ fn test ( ) {
10349+ let clock = Clock {
10350+ slot : 6 ,
10351+ epoch_start_timestamp : 0 ,
10352+ epoch : 0 ,
10353+ leader_schedule_epoch : 0 ,
10354+ unix_timestamp : 0 ,
10355+ } ;
10356+
10357+ let mut oracle_price = get_pyth_price ( 100 , 6 ) ;
10358+ let oracle_price_key =
10359+ Pubkey :: from_str ( "J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix" ) . unwrap ( ) ;
10360+ let pyth_program = crate :: ids:: pyth_program:: id ( ) ;
10361+ create_account_info ! (
10362+ oracle_price,
10363+ & oracle_price_key,
10364+ & pyth_program,
10365+ oracle_account_info
10366+ ) ;
10367+ let mut oracle_map = OracleMap :: load_one ( & oracle_account_info, clock. slot , None ) . unwrap ( ) ;
10368+
10369+ let mut market = PerpMarket {
10370+ amm : AMM {
10371+ base_asset_reserve : 100 * AMM_RESERVE_PRECISION ,
10372+ quote_asset_reserve : 100 * AMM_RESERVE_PRECISION ,
10373+ terminal_quote_asset_reserve : 100 * AMM_RESERVE_PRECISION ,
10374+ // bid_base_asset_reserve: 101 * AMM_RESERVE_PRECISION,
10375+ // bid_quote_asset_reserve: 99 * AMM_RESERVE_PRECISION,
10376+ // ask_base_asset_reserve: 99 * AMM_RESERVE_PRECISION,
10377+ // ask_quote_asset_reserve: 101 * AMM_RESERVE_PRECISION,
10378+ sqrt_k : 100 * AMM_RESERVE_PRECISION ,
10379+ peg_multiplier : 100 * PEG_PRECISION ,
10380+ max_slippage_ratio : 100 ,
10381+ max_fill_reserve_fraction : 100 ,
10382+ order_step_size : 1000 ,
10383+ order_tick_size : 1 ,
10384+ oracle : oracle_price_key,
10385+ max_spread : 1000 ,
10386+ base_spread : 0 ,
10387+ long_spread : 0 ,
10388+ short_spread : 0 ,
10389+ historical_oracle_data : HistoricalOracleData {
10390+ last_oracle_price_twap : oracle_price. twap ,
10391+ last_oracle_price_twap_5min : oracle_price. twap ,
10392+ last_oracle_price : oracle_price. agg . price ,
10393+ ..HistoricalOracleData :: default ( )
10394+ } ,
10395+ ..AMM :: default ( )
10396+ } ,
10397+ margin_ratio_initial : 1000 ,
10398+ margin_ratio_maintenance : 500 ,
10399+ status : MarketStatus :: Initialized ,
10400+ ..PerpMarket :: default ( )
10401+ } ;
10402+ market. status = MarketStatus :: Active ;
10403+ market. amm . max_base_asset_reserve = u128:: MAX ;
10404+ market. amm . min_base_asset_reserve = 0 ;
10405+ let ( new_ask_base_asset_reserve, new_ask_quote_asset_reserve) =
10406+ crate :: math:: amm_spread:: calculate_spread_reserves ( & market, PositionDirection :: Long )
10407+ . unwrap ( ) ;
10408+ let ( new_bid_base_asset_reserve, new_bid_quote_asset_reserve) =
10409+ crate :: math:: amm_spread:: calculate_spread_reserves ( & market, PositionDirection :: Short )
10410+ . unwrap ( ) ;
10411+ market. amm . ask_base_asset_reserve = new_ask_base_asset_reserve;
10412+ market. amm . bid_base_asset_reserve = new_bid_base_asset_reserve;
10413+ market. amm . ask_quote_asset_reserve = new_ask_quote_asset_reserve;
10414+ market. amm . bid_quote_asset_reserve = new_bid_quote_asset_reserve;
10415+ create_anchor_account_info ! ( market, PerpMarket , market_account_info) ;
10416+ let market_map = PerpMarketMap :: load_one ( & market_account_info, true ) . unwrap ( ) ;
10417+
10418+ let mut usdc_spot_market = SpotMarket {
10419+ market_index : 0 ,
10420+ oracle_source : OracleSource :: QuoteAsset ,
10421+ deposit_balance : SPOT_BALANCE_PRECISION ,
10422+ cumulative_deposit_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10423+ cumulative_borrow_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10424+ decimals : 6 ,
10425+ initial_asset_weight : SPOT_WEIGHT_PRECISION ,
10426+ maintenance_asset_weight : SPOT_WEIGHT_PRECISION ,
10427+ ..SpotMarket :: default ( )
10428+ } ;
10429+ create_anchor_account_info ! ( usdc_spot_market, SpotMarket , usdc_spot_market_account_info) ;
10430+
10431+ let mut sol_spot_market = SpotMarket {
10432+ market_index : 1 ,
10433+ deposit_balance : SPOT_BALANCE_PRECISION ,
10434+ cumulative_deposit_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10435+ cumulative_borrow_interest : SPOT_CUMULATIVE_INTEREST_PRECISION ,
10436+ oracle : oracle_price_key,
10437+ ..SpotMarket :: default_base_market ( )
10438+ } ;
10439+ create_anchor_account_info ! ( sol_spot_market, SpotMarket , sol_spot_market_account_info) ;
10440+
10441+ let spot_market_map = SpotMarketMap :: load_multiple (
10442+ vec ! [
10443+ & usdc_spot_market_account_info,
10444+ & sol_spot_market_account_info,
10445+ ] ,
10446+ true ,
10447+ )
10448+ . unwrap ( ) ;
10449+
10450+ let mut orders = [ Order :: default ( ) ; 32 ] ;
10451+ orders[ 0 ] = Order {
10452+ market_index : 0 ,
10453+ order_id : 1 ,
10454+ status : OrderStatus :: Open ,
10455+ order_type : OrderType :: Limit ,
10456+ market_type : MarketType :: Perp ,
10457+ ..Order :: default ( )
10458+ } ;
10459+ orders[ 1 ] = Order {
10460+ market_index : 1 ,
10461+ order_id : 2 ,
10462+ status : OrderStatus :: Open ,
10463+ order_type : OrderType :: TriggerMarket ,
10464+ market_type : MarketType :: Perp ,
10465+ reduce_only : true ,
10466+ ..Order :: default ( )
10467+ } ;
10468+ orders[ 2 ] = Order {
10469+ market_index : 0 ,
10470+ order_id : 2 ,
10471+ status : OrderStatus :: Open ,
10472+ order_type : OrderType :: TriggerMarket ,
10473+ market_type : MarketType :: Perp ,
10474+ reduce_only : true ,
10475+ ..Order :: default ( )
10476+ } ;
10477+ orders[ 3 ] = Order {
10478+ market_index : 0 ,
10479+ order_id : 2 ,
10480+ status : OrderStatus :: Open ,
10481+ order_type : OrderType :: TriggerMarket ,
10482+ market_type : MarketType :: Spot ,
10483+ reduce_only : true ,
10484+ ..Order :: default ( )
10485+ } ;
10486+ orders[ 4 ] = Order {
10487+ market_index : 0 ,
10488+ order_id : 2 ,
10489+ status : OrderStatus :: Open ,
10490+ order_type : OrderType :: TriggerLimit ,
10491+ market_type : MarketType :: Perp ,
10492+ reduce_only : true ,
10493+ ..Order :: default ( )
10494+ } ;
10495+
10496+ let mut user = User {
10497+ authority : Pubkey :: from_str ( "My11111111111111111111111111111111111111111" ) . unwrap ( ) , // different authority than filler
10498+ orders,
10499+ perp_positions : get_positions ( PerpPosition {
10500+ market_index : 0 ,
10501+ base_asset_amount : BASE_PRECISION_I64 ,
10502+ open_orders : 2 ,
10503+ open_bids : 100 * BASE_PRECISION_I64 ,
10504+ open_asks : -BASE_PRECISION_I64 ,
10505+ ..PerpPosition :: default ( )
10506+ } ) ,
10507+ spot_positions : get_spot_positions ( SpotPosition {
10508+ market_index : 1 ,
10509+ balance_type : SpotBalanceType :: Deposit ,
10510+ scaled_balance : SPOT_BALANCE_PRECISION_U64 ,
10511+ open_orders : 2 ,
10512+ open_bids : 100 * LAMPORTS_PER_SOL_I64 ,
10513+ open_asks : -LAMPORTS_PER_SOL_I64 ,
10514+ ..SpotPosition :: default ( )
10515+ } ) ,
10516+ ..User :: default ( )
10517+ } ;
10518+
10519+ cancel_reduce_only_trigger_orders (
10520+ & mut user,
10521+ & Pubkey :: default ( ) ,
10522+ Some ( & Pubkey :: default ( ) ) ,
10523+ & market_map,
10524+ & spot_market_map,
10525+ & mut oracle_map,
10526+ 0 ,
10527+ 0 ,
10528+ 0 ,
10529+ )
10530+ . unwrap ( ) ;
10531+
10532+ assert_eq ! ( user. orders[ 0 ] . status, OrderStatus :: Open ) ;
10533+ assert_eq ! ( user. orders[ 1 ] . status, OrderStatus :: Open ) ;
10534+ assert_eq ! ( user. orders[ 2 ] . status, OrderStatus :: Canceled ) ;
10535+ assert_eq ! ( user. orders[ 3 ] . status, OrderStatus :: Open ) ;
10536+ assert_eq ! ( user. orders[ 4 ] . status, OrderStatus :: Canceled ) ;
10537+
10538+ }
10539+ }
10540+
1031810541pub mod insert_maker_order_info {
1031910542 use crate :: controller:: orders:: insert_maker_order_info;
1032010543 use crate :: controller:: position:: PositionDirection ;
0 commit comments