1- use std:: collections:: BTreeMap ;
2-
31use anchor_lang:: { prelude:: * , Accounts , Key , Result } ;
42use anchor_spl:: token_interface:: { Mint , TokenAccount , TokenInterface } ;
53
@@ -15,10 +13,7 @@ use crate::{
1513 math:: {
1614 self ,
1715 casting:: Cast ,
18- constants:: {
19- PERCENTAGE_PRECISION , PERCENTAGE_PRECISION_I128 , PERCENTAGE_PRECISION_I64 ,
20- PERCENTAGE_PRECISION_U64 , PRICE_PRECISION , PRICE_PRECISION_I128 , QUOTE_PRECISION_I128 ,
21- } ,
16+ constants:: { PERCENTAGE_PRECISION_I64 , PRICE_PRECISION } ,
2217 oracle:: { is_oracle_valid_for_action, oracle_validity, DriftAction } ,
2318 safe_math:: SafeMath ,
2419 } ,
@@ -27,9 +22,9 @@ use crate::{
2722 constituent_map:: { ConstituentMap , ConstituentSet } ,
2823 events:: { emit_stack, LPMintRedeemRecord , LPSwapRecord } ,
2924 lp_pool:: {
30- calculate_target_weight , AmmConstituentDatum , AmmConstituentMappingFixed , Constituent ,
31- ConstituentCorrelationsFixed , ConstituentTargetBaseFixed , LPPool , TargetsDatum ,
32- WeightValidationFlags , LP_POOL_SWAP_AUM_UPDATE_DELAY ,
25+ update_constituent_target_base_for_derivatives , AmmConstituentDatum ,
26+ AmmConstituentMappingFixed , Constituent , ConstituentCorrelationsFixed ,
27+ ConstituentTargetBaseFixed , LPPool , TargetsDatum , LP_POOL_SWAP_AUM_UPDATE_DELAY ,
3328 MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC ,
3429 } ,
3530 oracle:: OraclePriceData ,
@@ -199,6 +194,7 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
199194 let state = & ctx. accounts . state ;
200195
201196 let slot = Clock :: get ( ) ?. slot ;
197+ let now = Clock :: get ( ) ?. unix_timestamp ;
202198
203199 let remaining_accounts = & mut ctx. remaining_accounts . iter ( ) . peekable ( ) ;
204200
@@ -251,88 +247,14 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
251247 "Amm cache PDA does not match expected PDA"
252248 ) ?;
253249
254- let mut aum: u128 = 0 ;
255- let mut crypto_delta = 0_i128 ;
256- let mut oldest_slot = u64:: MAX ;
257- let mut derivative_groups: BTreeMap < u16 , Vec < u16 > > = BTreeMap :: new ( ) ;
258- for i in 0 ..lp_pool. constituents as usize {
259- let constituent = constituent_map. get_ref ( & ( i as u16 ) ) ?;
260- if slot. saturating_sub ( constituent. last_oracle_slot )
261- > constituent. oracle_staleness_threshold
262- {
263- msg ! (
264- "Constituent {} oracle slot is too stale: {}, current slot: {}" ,
265- constituent. constituent_index,
266- constituent. last_oracle_slot,
267- slot
268- ) ;
269- return Err ( ErrorCode :: ConstituentOracleStale . into ( ) ) ;
270- }
271-
272- if constituent. constituent_derivative_index >= 0 && constituent. derivative_weight != 0 {
273- if !derivative_groups. contains_key ( & ( constituent. constituent_derivative_index as u16 ) ) {
274- derivative_groups. insert (
275- constituent. constituent_derivative_index as u16 ,
276- vec ! [ constituent. constituent_index] ,
277- ) ;
278- } else {
279- derivative_groups
280- . get_mut ( & ( constituent. constituent_derivative_index as u16 ) )
281- . unwrap ( )
282- . push ( constituent. constituent_index ) ;
283- }
284- }
285-
286- let spot_market = spot_market_map. get_ref ( & constituent. spot_market_index ) ?;
287-
288- let oracle_slot = constituent. last_oracle_slot ;
289-
290- if oracle_slot < oldest_slot {
291- oldest_slot = oracle_slot;
292- }
293-
294- let ( numerator_scale, denominator_scale) = if spot_market. decimals > 6 {
295- ( 10_i128 . pow ( spot_market. decimals - 6 ) , 1 )
296- } else {
297- ( 1 , 10_i128 . pow ( 6 - spot_market. decimals ) )
298- } ;
299-
300- let constituent_aum = constituent
301- . get_full_balance ( & spot_market) ?
302- . safe_mul ( numerator_scale) ?
303- . safe_div ( denominator_scale) ?
304- . safe_mul ( constituent. last_oracle_price as i128 ) ?
305- . safe_div ( PRICE_PRECISION_I128 ) ?
306- . max ( 0 ) ;
307- msg ! (
308- "constituent: {}, aum: {}, deriv index: {}" ,
309- constituent. constituent_index,
310- constituent_aum,
311- constituent. constituent_derivative_index
312- ) ;
313- if constituent. constituent_index != lp_pool. usdc_consituent_index
314- && constituent. constituent_derivative_index != lp_pool. usdc_consituent_index as i16
315- {
316- let constituent_target_notional = constituent_target_base
317- . get ( constituent. constituent_index as u32 )
318- . target_base
319- . safe_mul ( constituent. last_oracle_price ) ?
320- . safe_div ( 10_i64 . pow ( constituent. decimals as u32 ) ) ?;
321- crypto_delta = crypto_delta. safe_add ( constituent_target_notional. cast ( ) ?) ?;
322- }
323- aum = aum. safe_add ( constituent_aum. cast ( ) ?) ?;
324- }
325-
326- let mut aum_i128 = aum. cast :: < i128 > ( ) ?;
327- for cache_datum in amm_cache. iter ( ) {
328- aum_i128 -= cache_datum. quote_owed_from_lp_pool as i128 ;
329- }
330- aum = aum_i128. max ( 0i128 ) . cast :: < u128 > ( ) ?;
331-
332- lp_pool. oldest_oracle_slot = oldest_slot;
333- lp_pool. last_aum = aum;
334- lp_pool. last_aum_slot = slot;
335- lp_pool. last_aum_ts = Clock :: get ( ) ?. unix_timestamp ;
250+ let ( aum, crypto_delta, derivative_groups) = lp_pool. update_aum (
251+ now,
252+ slot,
253+ & constituent_map,
254+ & spot_market_map,
255+ & constituent_target_base,
256+ & amm_cache,
257+ ) ?;
336258
337259 // Set USDC stable weight
338260 let total_stable_target_base = aum
@@ -341,16 +263,7 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
341263 . max ( 0_i128 ) ;
342264 constituent_target_base
343265 . get_mut ( lp_pool. usdc_consituent_index as u32 )
344- . target_base = total_stable_target_base
345- . safe_mul (
346- 10_i128 . pow (
347- constituent_map
348- . get_ref ( & lp_pool. usdc_consituent_index ) ?
349- . decimals as u32 ,
350- ) ,
351- ) ?
352- . safe_div ( QUOTE_PRECISION_I128 ) ?
353- . cast :: < i64 > ( ) ?;
266+ . target_base = total_stable_target_base. cast :: < i64 > ( ) ?;
354267
355268 msg ! (
356269 "stable target base: {}" ,
@@ -361,75 +274,13 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
361274 msg ! ( "aum: {}, crypto_delta: {}" , aum, crypto_delta) ;
362275 msg ! ( "derivative groups: {:?}" , derivative_groups) ;
363276
364- // Handle all other derivatives
365- for ( parent_index, constituent_indexes) in derivative_groups. iter ( ) {
366- let parent_constituent = constituent_map. get_ref ( & ( parent_index) ) ?;
367- let parent_target_base = constituent_target_base
368- . get ( * parent_index as u32 )
369- . target_base ;
370- let target_parent_weight = calculate_target_weight (
371- parent_target_base,
372- & * spot_market_map. get_ref ( & parent_constituent. spot_market_index ) ?,
373- parent_constituent. last_oracle_price ,
374- aum,
375- WeightValidationFlags :: NONE ,
376- ) ?;
377- let mut derivative_weights_sum = 0 ;
378- for constituent_index in constituent_indexes {
379- let constituent = constituent_map. get_ref ( constituent_index) ?;
380- if constituent. last_oracle_price
381- < parent_constituent
382- . last_oracle_price
383- . safe_mul ( constituent. constituent_derivative_depeg_threshold as i64 ) ?
384- . safe_div ( PERCENTAGE_PRECISION_I64 ) ?
385- {
386- msg ! (
387- "Constituent {} last oracle price {} is too low compared to parent constituent {} last oracle price {}. Assuming depegging and setting target base to 0." ,
388- constituent. constituent_index,
389- constituent. last_oracle_price,
390- parent_constituent. constituent_index,
391- parent_constituent. last_oracle_price
392- ) ;
393- constituent_target_base
394- . get_mut ( * constituent_index as u32 )
395- . target_base = 0_i64 ;
396- continue ;
397- }
398-
399- derivative_weights_sum += constituent. derivative_weight ;
400-
401- let target_weight = target_parent_weight
402- . safe_mul ( constituent. derivative_weight as i64 ) ?
403- . safe_div ( PERCENTAGE_PRECISION_I64 ) ?;
404-
405- msg ! (
406- "constituent: {}, target weight: {}" ,
407- constituent_index,
408- target_weight,
409- ) ;
410- let target_base = lp_pool
411- . last_aum
412- . cast :: < i128 > ( ) ?
413- . safe_mul ( target_weight as i128 ) ?
414- . safe_div ( PERCENTAGE_PRECISION_I128 ) ?
415- . safe_mul ( 10_i128 . pow ( constituent. decimals as u32 ) ) ?
416- . safe_div ( constituent. last_oracle_price as i128 ) ?;
417-
418- msg ! (
419- "constituent: {}, target base: {}" ,
420- constituent_index,
421- target_base
422- ) ;
423- constituent_target_base
424- . get_mut ( * constituent_index as u32 )
425- . target_base = target_base. cast :: < i64 > ( ) ?;
426- }
427- constituent_target_base
428- . get_mut ( * parent_index as u32 )
429- . target_base = parent_target_base
430- . safe_mul ( PERCENTAGE_PRECISION_U64 . safe_sub ( derivative_weights_sum) ? as i64 ) ?
431- . safe_div ( PERCENTAGE_PRECISION_I64 ) ?;
432- }
277+ update_constituent_target_base_for_derivatives (
278+ aum,
279+ & derivative_groups,
280+ & constituent_map,
281+ & spot_market_map,
282+ & mut constituent_target_base,
283+ ) ?;
433284
434285 Ok ( ( ) )
435286}
0 commit comments