@@ -13,7 +13,7 @@ use crate::state::fill_mode::FillMode;
1313use crate :: state:: protected_maker_mode_config:: ProtectedMakerParams ;
1414use crate :: state:: user:: OrderBitFlag ;
1515use crate :: {
16- load, math, FeeTier , State , BASE_PRECISION_I128 , FEE_ADJUSTMENT_MAX ,
16+ load, math, FeeTier , State , BASE_PRECISION_I128 , FEE_ADJUSTMENT_MAX , MARGIN_PRECISION_I128 ,
1717 MAX_PREDICTION_MARKET_PRICE , MAX_PREDICTION_MARKET_PRICE_I64 , OPEN_ORDER_MARGIN_REQUIREMENT ,
1818 PERCENTAGE_PRECISION , PERCENTAGE_PRECISION_U64 , PRICE_PRECISION_I128 , PRICE_PRECISION_U64 ,
1919 QUOTE_PRECISION_I128 , SPOT_WEIGHT_PRECISION , SPOT_WEIGHT_PRECISION_I128 ,
@@ -936,24 +936,33 @@ pub fn calculate_max_perp_order_size(
936936 MAX_PREDICTION_MARKET_PRICE_I64 . safe_sub ( oracle_price_data_price) ?
937937 } ;
938938
939- let calculate_order_size_and_margin_ratio = |margin_ratio : u32 | {
939+ let calculate_order_size_and_margin_ratio = |margin_ratio : u32 , margin_ratio_delta : i32 | {
940+ let free_collateral_from_margin_ratio_delta = worst_case_base_asset_amount
941+ . safe_mul ( oracle_price. cast ( ) ?) ?
942+ . safe_div ( BASE_PRECISION_I128 ) ?
943+ . safe_mul ( margin_ratio_delta. cast ( ) ?) ?
944+ . safe_div ( MARGIN_PRECISION_I128 . cast ( ) ?) ?;
945+
940946 let new_order_size = free_collateral_before
941947 . safe_add ( free_collateral_released) ?
948+ . safe_sub ( free_collateral_from_margin_ratio_delta) ?
942949 . safe_sub ( OPEN_ORDER_MARGIN_REQUIREMENT . cast ( ) ?) ?
943- . safe_mul ( BASE_PRECISION_I128 / QUOTE_PRECISION_I128 ) ?
950+ . safe_mul ( BASE_PRECISION_I128 ) ?
944951 . safe_mul ( MARGIN_PRECISION_U128 . cast ( ) ?) ?
945952 . safe_div ( margin_ratio. cast ( ) ?) ?
946953 . safe_mul ( PRICE_PRECISION_I128 ) ?
947954 . safe_div ( oracle_price. cast ( ) ?) ?
948955 . safe_mul ( PRICE_PRECISION_I128 ) ?
949956 . safe_div ( quote_oracle_price. cast ( ) ?) ?
957+ . safe_div ( QUOTE_PRECISION_I128 ) ?
950958 . cast :: < u64 > ( ) ?;
951959
960+ let worst_case_base_asset_amount =
961+ worst_case_base_asset_amount. safe_add ( new_order_size. cast ( ) ?) ?;
962+
952963 let new_margin_ratio = perp_market
953964 . get_margin_ratio (
954- worst_case_base_asset_amount
955- . unsigned_abs ( )
956- . safe_add ( new_order_size. cast ( ) ?) ?,
965+ worst_case_base_asset_amount. unsigned_abs ( ) ,
957966 MarginRequirementType :: Initial ,
958967 user_high_leverage_mode,
959968 ) ?
@@ -964,15 +973,20 @@ pub fn calculate_max_perp_order_size(
964973
965974 let mut order_size = 0_u64 ;
966975 let mut updated_margin_ratio = margin_ratio;
976+ let mut margin_ratio_delta = 0 ;
967977 for _ in 0 ..6 {
968978 let ( new_order_size, new_margin_ratio) =
969- calculate_order_size_and_margin_ratio ( updated_margin_ratio) ?;
979+ calculate_order_size_and_margin_ratio ( updated_margin_ratio, margin_ratio_delta ) ?;
970980 order_size = new_order_size;
971- updated_margin_ratio = new_margin_ratio;
972981
973- if new_margin_ratio == margin_ratio {
982+ if new_margin_ratio == updated_margin_ratio {
974983 break ;
975984 }
985+
986+ margin_ratio_delta = new_margin_ratio
987+ . cast :: < i32 > ( ) ?
988+ . safe_sub ( margin_ratio. cast :: < i32 > ( ) ?) ?;
989+ updated_margin_ratio = new_margin_ratio;
976990 }
977991
978992 standardize_base_asset_amount (
0 commit comments