@@ -10593,6 +10593,228 @@ pub mod force_cancel_orders {
1059310593 }
1059410594}
1059510595
10596+ pub mod cancel_reduce_only_trigger_orders {
10597+ use std::str::FromStr;
10598+
10599+ use anchor_lang::prelude::Clock;
10600+
10601+ use crate::controller::orders::cancel_reduce_only_trigger_orders;
10602+ use crate::controller::position::PositionDirection;
10603+ use crate::create_account_info;
10604+ use crate::create_anchor_account_info;
10605+ use crate::math::constants::{
10606+ AMM_RESERVE_PRECISION, BASE_PRECISION_I64, LAMPORTS_PER_SOL_I64, PEG_PRECISION,
10607+ SPOT_BALANCE_PRECISION, SPOT_BALANCE_PRECISION_U64, SPOT_CUMULATIVE_INTEREST_PRECISION,
10608+ SPOT_WEIGHT_PRECISION,
10609+ };
10610+ use crate::state::oracle::HistoricalOracleData;
10611+ use crate::state::oracle::OracleSource;
10612+ use crate::state::perp_market::{PerpMarket, AMM};
10613+ use crate::state::perp_market_map::PerpMarketMap;
10614+ use crate::state::spot_market::{SpotBalanceType, SpotMarket};
10615+ use crate::state::spot_market_map::SpotMarketMap;
10616+ use crate::state::state::State;
10617+ use crate::state::user::{MarketType, OrderStatus, OrderType, SpotPosition, User};
10618+ use crate::test_utils::*;
10619+ use crate::test_utils::{
10620+ create_account_info, get_positions, get_pyth_price, get_spot_positions,
10621+ };
10622+
10623+ use super::*;
10624+
10625+ #[test]
10626+ fn test() {
10627+ let clock = Clock {
10628+ slot: 6,
10629+ epoch_start_timestamp: 0,
10630+ epoch: 0,
10631+ leader_schedule_epoch: 0,
10632+ unix_timestamp: 0,
10633+ };
10634+
10635+ let mut oracle_price = get_pyth_price(100, 6);
10636+ let oracle_price_key =
10637+ Pubkey::from_str("J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix").unwrap();
10638+ let pyth_program = crate::ids::pyth_program::id();
10639+ create_account_info!(
10640+ oracle_price,
10641+ &oracle_price_key,
10642+ &pyth_program,
10643+ oracle_account_info
10644+ );
10645+ let mut oracle_map = OracleMap::load_one(&oracle_account_info, clock.slot, None).unwrap();
10646+
10647+ let mut market = PerpMarket {
10648+ amm: AMM {
10649+ base_asset_reserve: 100 * AMM_RESERVE_PRECISION,
10650+ quote_asset_reserve: 100 * AMM_RESERVE_PRECISION,
10651+ terminal_quote_asset_reserve: 100 * AMM_RESERVE_PRECISION,
10652+ // bid_base_asset_reserve: 101 * AMM_RESERVE_PRECISION,
10653+ // bid_quote_asset_reserve: 99 * AMM_RESERVE_PRECISION,
10654+ // ask_base_asset_reserve: 99 * AMM_RESERVE_PRECISION,
10655+ // ask_quote_asset_reserve: 101 * AMM_RESERVE_PRECISION,
10656+ sqrt_k: 100 * AMM_RESERVE_PRECISION,
10657+ peg_multiplier: 100 * PEG_PRECISION,
10658+ max_slippage_ratio: 100,
10659+ max_fill_reserve_fraction: 100,
10660+ order_step_size: 1000,
10661+ order_tick_size: 1,
10662+ oracle: oracle_price_key,
10663+ max_spread: 1000,
10664+ base_spread: 0,
10665+ long_spread: 0,
10666+ short_spread: 0,
10667+ historical_oracle_data: HistoricalOracleData {
10668+ last_oracle_price_twap: oracle_price.twap,
10669+ last_oracle_price_twap_5min: oracle_price.twap,
10670+ last_oracle_price: oracle_price.agg.price,
10671+ ..HistoricalOracleData::default()
10672+ },
10673+ ..AMM::default()
10674+ },
10675+ margin_ratio_initial: 1000,
10676+ margin_ratio_maintenance: 500,
10677+ status: MarketStatus::Initialized,
10678+ ..PerpMarket::default()
10679+ };
10680+ market.status = MarketStatus::Active;
10681+ market.amm.max_base_asset_reserve = u128::MAX;
10682+ market.amm.min_base_asset_reserve = 0;
10683+ let (new_ask_base_asset_reserve, new_ask_quote_asset_reserve) =
10684+ crate::math::amm_spread::calculate_spread_reserves(&market, PositionDirection::Long)
10685+ .unwrap();
10686+ let (new_bid_base_asset_reserve, new_bid_quote_asset_reserve) =
10687+ crate::math::amm_spread::calculate_spread_reserves(&market, PositionDirection::Short)
10688+ .unwrap();
10689+ market.amm.ask_base_asset_reserve = new_ask_base_asset_reserve;
10690+ market.amm.bid_base_asset_reserve = new_bid_base_asset_reserve;
10691+ market.amm.ask_quote_asset_reserve = new_ask_quote_asset_reserve;
10692+ market.amm.bid_quote_asset_reserve = new_bid_quote_asset_reserve;
10693+ create_anchor_account_info!(market, PerpMarket, market_account_info);
10694+ let market_map = PerpMarketMap::load_one(&market_account_info, true).unwrap();
10695+
10696+ let mut usdc_spot_market = SpotMarket {
10697+ market_index: 0,
10698+ oracle_source: OracleSource::QuoteAsset,
10699+ deposit_balance: SPOT_BALANCE_PRECISION,
10700+ cumulative_deposit_interest: SPOT_CUMULATIVE_INTEREST_PRECISION,
10701+ cumulative_borrow_interest: SPOT_CUMULATIVE_INTEREST_PRECISION,
10702+ decimals: 6,
10703+ initial_asset_weight: SPOT_WEIGHT_PRECISION,
10704+ maintenance_asset_weight: SPOT_WEIGHT_PRECISION,
10705+ ..SpotMarket::default()
10706+ };
10707+ create_anchor_account_info!(usdc_spot_market, SpotMarket, usdc_spot_market_account_info);
10708+
10709+ let mut sol_spot_market = SpotMarket {
10710+ market_index: 1,
10711+ deposit_balance: SPOT_BALANCE_PRECISION,
10712+ cumulative_deposit_interest: SPOT_CUMULATIVE_INTEREST_PRECISION,
10713+ cumulative_borrow_interest: SPOT_CUMULATIVE_INTEREST_PRECISION,
10714+ oracle: oracle_price_key,
10715+ ..SpotMarket::default_base_market()
10716+ };
10717+ create_anchor_account_info!(sol_spot_market, SpotMarket, sol_spot_market_account_info);
10718+
10719+ let spot_market_map = SpotMarketMap::load_multiple(
10720+ vec![
10721+ &usdc_spot_market_account_info,
10722+ &sol_spot_market_account_info,
10723+ ],
10724+ true,
10725+ )
10726+ .unwrap();
10727+
10728+ let mut orders = [Order::default(); 32];
10729+ orders[0] = Order {
10730+ market_index: 0,
10731+ order_id: 1,
10732+ status: OrderStatus::Open,
10733+ order_type: OrderType::Limit,
10734+ market_type: MarketType::Perp,
10735+ ..Order::default()
10736+ };
10737+ orders[1] = Order {
10738+ market_index: 1,
10739+ order_id: 2,
10740+ status: OrderStatus::Open,
10741+ order_type: OrderType::TriggerMarket,
10742+ market_type: MarketType::Perp,
10743+ reduce_only: true,
10744+ ..Order::default()
10745+ };
10746+ orders[2] = Order {
10747+ market_index: 0,
10748+ order_id: 2,
10749+ status: OrderStatus::Open,
10750+ order_type: OrderType::TriggerMarket,
10751+ market_type: MarketType::Perp,
10752+ reduce_only: true,
10753+ ..Order::default()
10754+ };
10755+ orders[3] = Order {
10756+ market_index: 0,
10757+ order_id: 2,
10758+ status: OrderStatus::Open,
10759+ order_type: OrderType::TriggerMarket,
10760+ market_type: MarketType::Spot,
10761+ reduce_only: true,
10762+ ..Order::default()
10763+ };
10764+ orders[4] = Order {
10765+ market_index: 0,
10766+ order_id: 2,
10767+ status: OrderStatus::Open,
10768+ order_type: OrderType::TriggerLimit,
10769+ market_type: MarketType::Perp,
10770+ reduce_only: true,
10771+ ..Order::default()
10772+ };
10773+
10774+ let mut user = User {
10775+ authority: Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap(), // different authority than filler
10776+ orders,
10777+ perp_positions: get_positions(PerpPosition {
10778+ market_index: 0,
10779+ base_asset_amount: BASE_PRECISION_I64,
10780+ open_orders: 2,
10781+ open_bids: 100 * BASE_PRECISION_I64,
10782+ open_asks: -BASE_PRECISION_I64,
10783+ ..PerpPosition::default()
10784+ }),
10785+ spot_positions: get_spot_positions(SpotPosition {
10786+ market_index: 1,
10787+ balance_type: SpotBalanceType::Deposit,
10788+ scaled_balance: SPOT_BALANCE_PRECISION_U64,
10789+ open_orders: 2,
10790+ open_bids: 100 * LAMPORTS_PER_SOL_I64,
10791+ open_asks: -LAMPORTS_PER_SOL_I64,
10792+ ..SpotPosition::default()
10793+ }),
10794+ ..User::default()
10795+ };
10796+
10797+ cancel_reduce_only_trigger_orders(
10798+ &mut user,
10799+ &Pubkey::default(),
10800+ Some(&Pubkey::default()),
10801+ &market_map,
10802+ &spot_market_map,
10803+ &mut oracle_map,
10804+ 0,
10805+ 0,
10806+ 0,
10807+ )
10808+ .unwrap();
10809+
10810+ assert_eq!(user.orders[0].status, OrderStatus::Open);
10811+ assert_eq!(user.orders[1].status, OrderStatus::Open);
10812+ assert_eq!(user.orders[2].status, OrderStatus::Canceled);
10813+ assert_eq!(user.orders[3].status, OrderStatus::Open);
10814+ assert_eq!(user.orders[4].status, OrderStatus::Canceled);
10815+ }
10816+ }
10817+
1059610818pub mod insert_maker_order_info {
1059710819 use crate::controller::orders::insert_maker_order_info;
1059810820 use crate::controller::position::PositionDirection;
0 commit comments