|
| 1 | +use crate::state::perp_market_map::MarketSet; |
1 | 2 | use crate::{controller, load_mut}; |
2 | 3 | use crate::controller::token::{receive, send_from_program_vault_with_signature_seeds}; |
3 | 4 | use crate::error::ErrorCode; |
4 | 5 | use crate::ids::{admin_hot_wallet, lp_pool_swap_wallet}; |
5 | | -use crate::instructions::optional_accounts::get_token_mint; |
| 6 | +use crate::instructions::optional_accounts::{get_token_mint, load_maps, AccountMaps}; |
6 | 7 | use crate::math::constants::{PRICE_PRECISION_U64, QUOTE_SPOT_MARKET_INDEX}; |
7 | 8 | use crate::math::safe_math::SafeMath; |
8 | | -use crate::state::amm_cache::AmmCache; |
| 9 | +use crate::state::amm_cache::{AmmCache, AMM_POSITIONS_CACHE}; |
9 | 10 | use crate::state::lp_pool::{ |
10 | 11 | AmmConstituentDatum, AmmConstituentMapping, Constituent, ConstituentCorrelations, |
11 | 12 | ConstituentTargetBase, LPPool, TargetsDatum, AMM_MAP_PDA_SEED, |
@@ -896,6 +897,90 @@ pub fn handle_update_perp_market_lp_pool_status( |
896 | 897 | Ok(()) |
897 | 898 | } |
898 | 899 |
|
| 900 | +pub fn handle_update_initial_amm_cache_info<'c: 'info, 'info>( |
| 901 | + ctx: Context<'_, '_, 'c, 'info, UpdateInitialAmmCacheInfo<'info>>, |
| 902 | +) -> Result<()> { |
| 903 | + let amm_cache = &mut ctx.accounts.amm_cache; |
| 904 | + let slot = Clock::get()?.slot; |
| 905 | + let state = &ctx.accounts.state; |
| 906 | + |
| 907 | + let AccountMaps { |
| 908 | + perp_market_map, |
| 909 | + spot_market_map: _, |
| 910 | + mut oracle_map, |
| 911 | + } = load_maps( |
| 912 | + &mut ctx.remaining_accounts.iter().peekable(), |
| 913 | + &MarketSet::new(), |
| 914 | + &MarketSet::new(), |
| 915 | + Clock::get()?.slot, |
| 916 | + None, |
| 917 | + )?; |
| 918 | + |
| 919 | + for (_, perp_market_loader) in perp_market_map.0 { |
| 920 | + let perp_market = perp_market_loader.load()?; |
| 921 | + let oracle_data = oracle_map.get_price_data(&perp_market.oracle_id())?; |
| 922 | + let mm_oracle_data = perp_market.get_mm_oracle_price_data( |
| 923 | + *oracle_data, |
| 924 | + slot, |
| 925 | + &ctx.accounts.state.oracle_guard_rails.validity, |
| 926 | + )?; |
| 927 | + |
| 928 | + amm_cache.update_perp_market_fields(&perp_market)?; |
| 929 | + amm_cache.update_oracle_info( |
| 930 | + slot, |
| 931 | + perp_market.market_index, |
| 932 | + &mm_oracle_data, |
| 933 | + &perp_market, |
| 934 | + &state.oracle_guard_rails, |
| 935 | + )?; |
| 936 | + } |
| 937 | + |
| 938 | + Ok(()) |
| 939 | +} |
| 940 | +#[derive(Debug, Clone, Copy, AnchorSerialize, AnchorDeserialize, PartialEq, Eq)] |
| 941 | +pub struct OverrideAmmCacheParams { |
| 942 | + pub quote_owed_from_lp_pool: Option<i64>, |
| 943 | + pub last_settle_slot: Option<u64>, |
| 944 | + pub last_fee_pool_token_amount: Option<u128>, |
| 945 | + pub last_net_pnl_pool_token_amount: Option<i128>, |
| 946 | + pub amm_position_scalar: Option<u8>, |
| 947 | +} |
| 948 | + |
| 949 | +pub fn handle_override_amm_cache_info<'c: 'info, 'info>( |
| 950 | + ctx: Context<'_, '_, 'c, 'info, UpdateInitialAmmCacheInfo<'info>>, |
| 951 | + market_index: u16, |
| 952 | + override_params: OverrideAmmCacheParams, |
| 953 | +) -> Result<()> { |
| 954 | + let amm_cache = &mut ctx.accounts.amm_cache; |
| 955 | + |
| 956 | + let cache_entry = amm_cache.cache.get_mut(market_index as usize); |
| 957 | + if cache_entry.is_none() { |
| 958 | + msg!("No cache entry found for market index {}", market_index); |
| 959 | + return Ok(()); |
| 960 | + } |
| 961 | + |
| 962 | + let cache_entry = cache_entry.unwrap(); |
| 963 | + if let Some(quote_owed_from_lp_pool) = override_params.quote_owed_from_lp_pool { |
| 964 | + cache_entry.quote_owed_from_lp_pool = quote_owed_from_lp_pool; |
| 965 | + } |
| 966 | + if let Some(last_settle_slot) = override_params.last_settle_slot { |
| 967 | + cache_entry.last_settle_slot = last_settle_slot; |
| 968 | + } |
| 969 | + if let Some(last_fee_pool_token_amount) = override_params.last_fee_pool_token_amount { |
| 970 | + cache_entry.last_fee_pool_token_amount = last_fee_pool_token_amount; |
| 971 | + } |
| 972 | + if let Some(last_net_pnl_pool_token_amount) = override_params.last_net_pnl_pool_token_amount { |
| 973 | + cache_entry.last_net_pnl_pool_token_amount = last_net_pnl_pool_token_amount; |
| 974 | + } |
| 975 | + |
| 976 | + if let Some(amm_position_scalar) = override_params.amm_position_scalar { |
| 977 | + cache_entry.amm_position_scalar = amm_position_scalar; |
| 978 | + } |
| 979 | + |
| 980 | + Ok(()) |
| 981 | +} |
| 982 | + |
| 983 | + |
899 | 984 | #[derive(Accounts)] |
900 | 985 | #[instruction( |
901 | 986 | name: [u8; 32], |
@@ -1252,6 +1337,23 @@ pub struct UpdatePerpMarketLpPoolStatus<'info> { |
1252 | 1337 | pub state: Box<Account<'info, State>>, |
1253 | 1338 | #[account(mut)] |
1254 | 1339 | pub perp_market: AccountLoader<'info, PerpMarket>, |
1255 | | - #[account(mut)] |
| 1340 | + #[account(mut, seeds = [AMM_POSITIONS_CACHE.as_ref()], |
| 1341 | + bump = amm_cache.bump,)] |
| 1342 | + pub amm_cache: Box<Account<'info, AmmCache>>, |
| 1343 | +} |
| 1344 | + |
| 1345 | +#[derive(Accounts)] |
| 1346 | +pub struct UpdateInitialAmmCacheInfo<'info> { |
| 1347 | + #[account( |
| 1348 | + mut, |
| 1349 | + constraint = admin.key() == admin_hot_wallet::id() || admin.key() == state.admin |
| 1350 | + )] |
| 1351 | + pub state: Box<Account<'info, State>>, |
| 1352 | + pub admin: Signer<'info>, |
| 1353 | + #[account( |
| 1354 | + mut, |
| 1355 | + seeds = [AMM_POSITIONS_CACHE.as_ref()], |
| 1356 | + bump = amm_cache.bump, |
| 1357 | + )] |
1256 | 1358 | pub amm_cache: Box<Account<'info, AmmCache>>, |
1257 | 1359 | } |
0 commit comments