@@ -6,7 +6,6 @@ use anchor_lang::Discriminator;
66use anchor_spl:: associated_token:: get_associated_token_address_with_program_id;
77use anchor_spl:: token_interface:: Mint ;
88use anchor_spl:: token_interface:: { TokenAccount , TokenInterface } ;
9- use num_integer:: Integer ;
109use solana_program:: instruction:: Instruction ;
1110use solana_program:: pubkey;
1211use solana_program:: sysvar:: instructions:: {
@@ -36,7 +35,6 @@ use crate::math::oracle::is_oracle_valid_for_action;
3635use crate :: math:: oracle:: DriftAction ;
3736use crate :: math:: orders:: { estimate_price_from_side, find_bids_and_asks_from_users} ;
3837use crate :: math:: position:: calculate_base_asset_value_and_pnl_with_oracle_price;
39- use crate :: math:: safe_math:: SafeDivFloor ;
4038use crate :: math:: safe_math:: SafeMath ;
4139use crate :: math:: spot_balance:: get_token_amount;
4240use crate :: math:: spot_withdraw:: validate_spot_market_vault_amount;
@@ -3008,12 +3006,14 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
30083006 . cast :: < i128 > ( ) ?
30093007 . safe_sub ( calculate_net_user_pnl ( & perp_market. amm , oracle_data. price ) ?) ?;
30103008
3011- let amount_available =
3009+ let amm_amount_available =
30123010 net_pnl_pool_token_amount. safe_add ( fee_pool_token_amount. cast :: < i128 > ( ) ?) ?;
30133011
3014- if cached_info. last_net_pnl_pool_balance == 0 && cached_info. last_fee_pool_balance == 0 {
3015- cached_info. last_fee_pool_balance = fee_pool_token_amount;
3016- cached_info. last_net_pnl_pool_balance = net_pnl_pool_token_amount;
3012+ if cached_info. last_net_pnl_pool_token_amount == 0
3013+ && cached_info. last_fee_pool_token_amount == 0
3014+ {
3015+ cached_info. last_fee_pool_token_amount = fee_pool_token_amount;
3016+ cached_info. last_net_pnl_pool_token_amount = net_pnl_pool_token_amount;
30173017 continue ;
30183018 }
30193019
@@ -3090,16 +3090,26 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
30903090 continue ;
30913091 }
30923092
3093- let amount_to_send = amount_available
3093+ let amount_to_send = amm_amount_available
30943094 . abs_diff ( cached_info. get_last_available_amm_balance ( ) ?)
3095- . safe_div_ceil ( perp_market. lp_fee_transfer_scalar as u128 ) ?;
3096- if amount_available < 0 {
3097- controller:: token:: receive (
3095+ . safe_div_ceil ( perp_market. lp_fee_transfer_scalar as u128 ) ?
3096+ . cast :: < u64 > ( ) ?;
3097+ if amm_amount_available < cached_info. get_last_available_amm_balance ( ) ? {
3098+ let amount_to_send = if amount_to_send > constituent_token_account. amount {
3099+ cached_info. quote_owed_from_lp +=
3100+ amount_to_send. saturating_sub ( constituent_token_account. amount ) as i64 ;
3101+ constituent_token_account. amount
3102+ } else {
3103+ amount_to_send
3104+ } ;
3105+
3106+ controller:: token:: send_from_program_vault (
30983107 & ctx. accounts . token_program ,
30993108 constituent_token_account,
31003109 & ctx. accounts . quote_token_vault ,
31013110 & ctx. accounts . drift_signer ,
3102- amount_to_send. cast :: < u64 > ( ) ?,
3111+ state. signer_nonce ,
3112+ amount_to_send,
31033113 & Some ( mint) ,
31043114 ) ?;
31053115
@@ -3115,58 +3125,78 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31153125 lp_pool. last_aum = lp_pool
31163126 . last_aum
31173127 . saturating_sub ( amount_to_send. cast :: < u128 > ( ) ?) ;
3118- } else {
3119- controller:: token:: send_from_program_vault (
3120- & ctx. accounts . token_program ,
3121- & ctx. accounts . quote_token_vault ,
3122- constituent_token_account,
3123- & ctx. accounts . drift_signer ,
3124- state. signer_nonce ,
3125- amount_to_send. cast :: < u64 > ( ) ?,
3126- & Some ( mint) ,
3127- ) ?;
31283128
3129- // If both fees and pnl are up, take from both equally
3130- let precision_increase = SPOT_BALANCE_PRECISION . safe_div ( QUOTE_PRECISION ) ?;
3131- if fee_pool_token_amount > cached_info. last_fee_pool_balance
3132- && net_pnl_pool_token_amount > cached_info. last_net_pnl_pool_balance
3133- {
3134- let abs_scaled_fee_pool_token_delta = fee_pool_token_amount
3135- . abs_diff ( cached_info. last_fee_pool_balance )
3136- . safe_div_ceil ( perp_market. lp_fee_transfer_scalar as u128 ) ?;
3137-
3138- let abs_scaled_pnl_pool_token_delta = net_pnl_pool_token_amount
3139- . abs_diff ( cached_info. last_net_pnl_pool_balance )
3140- . safe_div_ceil ( perp_market. lp_fee_transfer_scalar as u128 ) ?;
3141-
3142- msg ! (
3143- "abs scaled fee pool token delta = {} abs scaled pnl pool token delta = {}" ,
3144- abs_scaled_fee_pool_token_delta,
3145- abs_scaled_pnl_pool_token_delta
3146- ) ;
3147- perp_market. amm . fee_pool . decrease_balance (
3148- abs_scaled_fee_pool_token_delta. safe_mul ( precision_increase) ?,
3149- ) ?;
3150- perp_market. pnl_pool . decrease_balance (
3151- abs_scaled_pnl_pool_token_delta. safe_mul ( precision_increase) ?,
3129+ cached_info. last_fee_pool_token_amount =
3130+ fee_pool_token_amount. safe_add ( amount_to_send as u128 ) ?;
3131+ } else {
3132+ let amount_to_send = if cached_info. quote_owed_from_lp > 0 {
3133+ if amount_to_send > cached_info. quote_owed_from_lp as u64 {
3134+ cached_info. quote_owed_from_lp = 0 ;
3135+ amount_to_send - cached_info. quote_owed_from_lp as u64
3136+ } else {
3137+ cached_info. quote_owed_from_lp -= amount_to_send as i64 ;
3138+ 0
3139+ }
3140+ } else {
3141+ amount_to_send
3142+ } ;
3143+
3144+ if amount_to_send > 0 {
3145+ controller:: token:: send_from_program_vault (
3146+ & ctx. accounts . token_program ,
3147+ & ctx. accounts . quote_token_vault ,
3148+ constituent_token_account,
3149+ & ctx. accounts . drift_signer ,
3150+ state. signer_nonce ,
3151+ amount_to_send. cast :: < u64 > ( ) ?,
3152+ & Some ( mint) ,
31523153 ) ?;
3153- } else if fee_pool_token_amount > cached_info. last_fee_pool_balance {
3154- perp_market
3155- . amm
3156- . fee_pool
3157- . decrease_balance ( ( amount_to_send as u128 ) . safe_mul ( precision_increase) ?) ?;
3158- } else if net_pnl_pool_token_amount > cached_info. last_net_pnl_pool_balance {
3159- perp_market
3160- . pnl_pool
3161- . decrease_balance ( ( amount_to_send as u128 ) . safe_mul ( precision_increase) ?) ?;
3162- }
3154+ // If both fees and pnl are up, take from both equally
3155+ let precision_increase = SPOT_BALANCE_PRECISION . safe_div ( QUOTE_PRECISION ) ?;
3156+ if fee_pool_token_amount > cached_info. last_fee_pool_token_amount
3157+ && net_pnl_pool_token_amount > cached_info. last_net_pnl_pool_token_amount
3158+ {
3159+ let abs_scaled_fee_pool_token_delta = fee_pool_token_amount
3160+ . abs_diff ( cached_info. last_fee_pool_token_amount )
3161+ . safe_div_ceil ( perp_market. lp_fee_transfer_scalar as u128 ) ?;
31633162
3164- lp_pool. cumulative_usdc_received_from_perp_markets = lp_pool
3165- . cumulative_usdc_received_from_perp_markets
3166- . saturating_add ( amount_to_send. cast :: < u128 > ( ) ?) ;
3167- lp_pool. last_aum = lp_pool
3168- . last_aum
3169- . saturating_add ( amount_to_send. cast :: < u128 > ( ) ?) ;
3163+ let abs_scaled_pnl_pool_token_delta = net_pnl_pool_token_amount
3164+ . abs_diff ( cached_info. last_net_pnl_pool_token_amount )
3165+ . safe_div_ceil ( perp_market. lp_fee_transfer_scalar as u128 ) ?;
3166+
3167+ perp_market. amm . fee_pool . decrease_balance (
3168+ abs_scaled_fee_pool_token_delta. safe_mul ( precision_increase) ?,
3169+ ) ?;
3170+ perp_market. pnl_pool . decrease_balance (
3171+ abs_scaled_pnl_pool_token_delta. safe_mul ( precision_increase) ?,
3172+ ) ?;
3173+
3174+ cached_info. last_fee_pool_token_amount =
3175+ fee_pool_token_amount. safe_sub ( abs_scaled_fee_pool_token_delta) ?;
3176+ cached_info. last_net_pnl_pool_token_amount = net_pnl_pool_token_amount
3177+ . safe_sub ( abs_scaled_pnl_pool_token_delta. cast :: < i128 > ( ) ?) ?;
3178+ } else if fee_pool_token_amount > cached_info. last_fee_pool_token_amount {
3179+ perp_market
3180+ . amm
3181+ . fee_pool
3182+ . decrease_balance ( ( amount_to_send as u128 ) . safe_mul ( precision_increase) ?) ?;
3183+ cached_info. last_fee_pool_token_amount =
3184+ fee_pool_token_amount. safe_sub ( amount_to_send as u128 ) ?;
3185+ } else if net_pnl_pool_token_amount > cached_info. last_net_pnl_pool_token_amount {
3186+ perp_market
3187+ . pnl_pool
3188+ . decrease_balance ( ( amount_to_send as u128 ) . safe_mul ( precision_increase) ?) ?;
3189+ cached_info. last_net_pnl_pool_token_amount =
3190+ net_pnl_pool_token_amount. safe_sub ( amount_to_send. cast :: < i128 > ( ) ?) ?;
3191+ }
3192+
3193+ lp_pool. cumulative_usdc_received_from_perp_markets = lp_pool
3194+ . cumulative_usdc_received_from_perp_markets
3195+ . saturating_add ( amount_to_send. cast :: < u128 > ( ) ?) ;
3196+ lp_pool. last_aum = lp_pool
3197+ . last_aum
3198+ . saturating_add ( amount_to_send. cast :: < u128 > ( ) ?) ;
3199+ }
31703200 }
31713201
31723202 lp_pool. last_aum_ts = clock. unix_timestamp ;
@@ -3175,8 +3205,6 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31753205 constituent_token_account. reload ( ) ?;
31763206 constituent. sync_token_balance ( constituent_token_account. amount ) ;
31773207
3178- cached_info. last_fee_pool_balance = fee_pool_token_amount;
3179- cached_info. last_net_pnl_pool_balance = net_pnl_pool_token_amount;
31803208 cached_info. last_settle_amount = amount_to_send. cast :: < u64 > ( ) ?;
31813209 cached_info. last_settle_ts = Clock :: get ( ) ?. unix_timestamp ;
31823210 }
@@ -3197,8 +3225,6 @@ pub fn handle_update_amm_cache<'c: 'info, 'info>(
31973225 let mut amm_cache: AccountZeroCopyMut < ' _ , CacheInfo , _ > =
31983226 ctx. accounts . amm_cache . load_zc_mut ( ) ?;
31993227
3200- let quote_market = & ctx. accounts . quote_market . load ( ) ?;
3201-
32023228 let expected_pda = & Pubkey :: create_program_address (
32033229 & [
32043230 AMM_POSITIONS_CACHE . as_ref ( ) ,
0 commit comments