11use crate :: controller:: amm:: { update_pnl_pool_and_user_balance, update_pool_balances} ;
22use crate :: controller:: funding:: settle_funding_payment;
3- use crate :: controller:: isolated_position:: transfer_isolated_perp_position_deposit;
43use crate :: controller:: orders:: { cancel_orders, validate_market_within_price_band} ;
54use crate :: controller:: position:: {
65 get_position_index, update_position_and_market, update_quote_asset_amount,
@@ -21,7 +20,10 @@ use crate::math::position::calculate_base_asset_value_with_expiry_price;
2120use crate :: math:: safe_math:: SafeMath ;
2221use crate :: math:: spot_balance:: get_token_amount;
2322
23+ use crate :: get_then_update_id;
24+ use crate :: math:: orders:: calculate_existing_position_fields_for_order_action;
2425use crate :: msg;
26+ use crate :: state:: events:: { OrderAction , OrderActionRecord , OrderRecord } ;
2527
2628use crate :: state:: events:: { OrderActionExplanation , SettlePnlExplanation , SettlePnlRecord } ;
2729use crate :: state:: oracle_map:: OracleMap ;
@@ -32,7 +34,7 @@ use crate::state::settle_pnl_mode::SettlePnlMode;
3234use crate :: state:: spot_market:: { SpotBalance , SpotBalanceType } ;
3335use crate :: state:: spot_market_map:: SpotMarketMap ;
3436use crate :: state:: state:: State ;
35- use crate :: state:: user:: { MarketType , User , UserStats } ;
37+ use crate :: state:: user:: { MarketType , Order , OrderStatus , OrderType , User , UserStats } ;
3638use crate :: validate;
3739use anchor_lang:: prelude:: Pubkey ;
3840use anchor_lang:: prelude:: * ;
@@ -484,6 +486,11 @@ pub fn settle_expired_position(
484486 let base_asset_amount = user. perp_positions [ position_index] . base_asset_amount ;
485487 let quote_entry_amount = user. perp_positions [ position_index] . quote_entry_amount ;
486488
489+ let user_position_direction_to_close =
490+ user. perp_positions [ position_index] . get_direction_to_close ( ) ;
491+ let user_existing_position_params_for_order_action = user. perp_positions [ position_index]
492+ . get_existing_position_params_for_order_action ( user_position_direction_to_close) ;
493+
487494 let position_delta = PositionDelta {
488495 quote_asset_amount : base_asset_value,
489496 base_asset_amount : -user. perp_positions [ position_index] . base_asset_amount ,
@@ -516,6 +523,80 @@ pub fn settle_expired_position(
516523 -pnl_to_settle_with_user. cast ( ) ?,
517524 ) ?;
518525
526+ if position_delta. base_asset_amount != 0 {
527+ // get ids for order fills
528+ let user_order_id = get_then_update_id ! ( user, next_order_id) ;
529+ let fill_record_id = get_then_update_id ! ( perp_market, next_fill_record_id) ;
530+
531+ let base_asset_amount = position_delta. base_asset_amount ;
532+ let user_existing_position_direction = user. perp_positions [ position_index] . get_direction ( ) ;
533+
534+ let user_order = Order {
535+ slot,
536+ base_asset_amount : base_asset_amount. unsigned_abs ( ) ,
537+ order_id : user_order_id,
538+ market_index : perp_market. market_index ,
539+ status : OrderStatus :: Open ,
540+ order_type : OrderType :: Market ,
541+ market_type : MarketType :: Perp ,
542+ direction : user_position_direction_to_close,
543+ existing_position_direction : user_existing_position_direction,
544+ ..Order :: default ( )
545+ } ;
546+
547+ emit ! ( OrderRecord {
548+ ts: now,
549+ user: * user_key,
550+ order: user_order
551+ } ) ;
552+
553+ let ( taker_existing_quote_entry_amount, taker_existing_base_asset_amount) =
554+ calculate_existing_position_fields_for_order_action (
555+ base_asset_amount. unsigned_abs ( ) ,
556+ user_existing_position_params_for_order_action,
557+ ) ?;
558+
559+ let fill_record = OrderActionRecord {
560+ ts : now,
561+ action : OrderAction :: Fill ,
562+ action_explanation : OrderActionExplanation :: MarketExpired ,
563+ market_index : perp_market. market_index ,
564+ market_type : MarketType :: Perp ,
565+ filler : None ,
566+ filler_reward : None ,
567+ fill_record_id : Some ( fill_record_id) ,
568+ base_asset_amount_filled : Some ( base_asset_amount. unsigned_abs ( ) ) ,
569+ quote_asset_amount_filled : Some ( base_asset_value. unsigned_abs ( ) ) ,
570+ taker_fee : Some ( fee. unsigned_abs ( ) ) ,
571+ maker_fee : None ,
572+ referrer_reward : None ,
573+ quote_asset_amount_surplus : None ,
574+ spot_fulfillment_method_fee : None ,
575+ taker : Some ( * user_key) ,
576+ taker_order_id : Some ( user_order_id) ,
577+ taker_order_direction : Some ( user_position_direction_to_close) ,
578+ taker_order_base_asset_amount : Some ( base_asset_amount. unsigned_abs ( ) ) ,
579+ taker_order_cumulative_base_asset_amount_filled : Some ( base_asset_amount. unsigned_abs ( ) ) ,
580+ taker_order_cumulative_quote_asset_amount_filled : Some ( base_asset_value. unsigned_abs ( ) ) ,
581+ maker : None ,
582+ maker_order_id : None ,
583+ maker_order_direction : None ,
584+ maker_order_base_asset_amount : None ,
585+ maker_order_cumulative_base_asset_amount_filled : None ,
586+ maker_order_cumulative_quote_asset_amount_filled : None ,
587+ oracle_price : perp_market. expiry_price ,
588+ bit_flags : 0 ,
589+ taker_existing_quote_entry_amount,
590+ taker_existing_base_asset_amount,
591+ maker_existing_quote_entry_amount : None ,
592+ maker_existing_base_asset_amount : None ,
593+ trigger_price : None ,
594+ builder_idx : None ,
595+ builder_fee : None ,
596+ } ;
597+ emit ! ( fill_record) ;
598+ }
599+
519600 update_settled_pnl ( user, position_index, pnl_to_settle_with_user. cast ( ) ?) ?;
520601
521602 perp_market. amm . base_asset_amount_with_amm = perp_market
0 commit comments