@@ -6,6 +6,7 @@ use crate::math::constants::{
66} ;
77use crate :: math:: position:: calculate_base_asset_value_and_pnl_with_oracle_price;
88
9+ use crate :: MARGIN_PRECISION ;
910use crate :: { validate, PRICE_PRECISION_I128 } ;
1011use crate :: { validation, PRICE_PRECISION_I64 } ;
1112
@@ -27,6 +28,7 @@ use crate::state::spot_market_map::SpotMarketMap;
2728use crate :: state:: user:: { MarketType , OrderFillSimulation , PerpPosition , User } ;
2829use num_integer:: Roots ;
2930use std:: cmp:: { max, min, Ordering } ;
31+ use std:: collections:: BTreeMap ;
3032
3133#[ cfg( test) ]
3234mod tests;
@@ -535,6 +537,12 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
535537 0 ,
536538 ) ?;
537539
540+ let perp_position_custom_margin_ratio = if context. margin_type == MarginRequirementType :: Initial {
541+ market_position. max_margin_ratio as u32
542+ } else {
543+ 0_u32
544+ } ;
545+
538546 let (
539547 perp_margin_requirement,
540548 weighted_pnl,
@@ -547,7 +555,7 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
547555 oracle_price_data,
548556 & strict_quote_price,
549557 context. margin_type ,
550- user_custom_margin_ratio,
558+ user_custom_margin_ratio. max ( perp_position_custom_margin_ratio ) ,
551559 user_high_leverage_mode,
552560 calculation. track_open_orders_fraction ( ) ,
553561 ) ?;
@@ -884,6 +892,42 @@ pub fn validate_spot_margin_trading(
884892 Ok ( ( ) )
885893}
886894
895+ pub fn get_margin_calculation_for_disable_high_leverage_mode (
896+ user : & mut User ,
897+ perp_market_map : & PerpMarketMap ,
898+ spot_market_map : & SpotMarketMap ,
899+ oracle_map : & mut OracleMap ,
900+ ) -> DriftResult < MarginCalculation > {
901+ let custom_margin_ratio_before = user. max_margin_ratio ;
902+
903+
904+ let mut perp_position_max_margin_ratio_map = BTreeMap :: new ( ) ;
905+ for ( index, position) in user. perp_positions . iter_mut ( ) . enumerate ( ) {
906+ if position. max_margin_ratio == 0 {
907+ continue ;
908+ }
909+
910+ perp_position_max_margin_ratio_map. insert ( index, position. max_margin_ratio ) ;
911+ position. max_margin_ratio = 0 ;
912+ }
913+
914+ let margin_buffer = MARGIN_PRECISION / 100 ; // 1% buffer
915+ let margin_calc = calculate_margin_requirement_and_total_collateral_and_liability_info (
916+ user,
917+ perp_market_map,
918+ spot_market_map,
919+ oracle_map,
920+ MarginContext :: standard ( MarginRequirementType :: Initial ) . margin_buffer ( margin_buffer) ,
921+ ) ?;
922+
923+ user. max_margin_ratio = custom_margin_ratio_before;
924+ for ( index, perp_position_max_margin_ratio) in perp_position_max_margin_ratio_map. iter ( ) {
925+ user. perp_positions [ * index] . max_margin_ratio = * perp_position_max_margin_ratio;
926+ }
927+
928+ Ok ( margin_calc)
929+ }
930+
887931pub fn calculate_user_equity (
888932 user : & User ,
889933 perp_market_map : & PerpMarketMap ,
0 commit comments