@@ -57,9 +57,10 @@ use crate::state::oracle::{
5757use crate :: state:: oracle_map:: OracleMap ;
5858use crate :: state:: paused_operations:: { InsuranceFundOperation , PerpOperation , SpotOperation } ;
5959use crate :: state:: perp_market:: {
60- ContractTier , ContractType , InsuranceClaim , MarketStatus , PerpMarket , PoolBalance , AMM ,
60+ AmmCache , CacheInfo , ContractTier , ContractType , InsuranceClaim , MarketStatus , PerpMarket ,
61+ PoolBalance , AMM , AMM_POSITIONS_CACHE ,
6162} ;
62- use crate :: state:: perp_market_map:: get_writable_perp_market_set;
63+ use crate :: state:: perp_market_map:: { get_writable_perp_market_set, MarketSet } ;
6364use crate :: state:: protected_maker_mode_config:: ProtectedMakerModeConfig ;
6465use crate :: state:: pyth_lazer_oracle:: { PythLazerOracle , PYTH_LAZER_ORACLE_SEED } ;
6566use crate :: state:: spot_market:: {
@@ -1055,6 +1056,22 @@ pub fn handle_initialize_perp_market(
10551056
10561057 safe_increment ! ( state. number_of_markets, 1 ) ;
10571058
1059+ let amm_cache = & mut ctx. accounts . amm_cache ;
1060+ let current_len = amm_cache. cache . len ( ) ;
1061+ amm_cache
1062+ . cache
1063+ . resize_with ( current_len + 1 , CacheInfo :: default) ;
1064+ let current_market_info = amm_cache. cache . get_mut ( current_len) . unwrap ( ) ;
1065+ current_market_info. slot = clock_slot;
1066+
1067+ current_market_info. oracle = perp_market. amm . oracle ;
1068+ current_market_info. oracle_source = u8:: from ( perp_market. amm . oracle_source ) ;
1069+ current_market_info. last_oracle_price_twap = perp_market
1070+ . amm
1071+ . historical_oracle_data
1072+ . last_oracle_price_twap ;
1073+ amm_cache. validate ( state) ?;
1074+
10581075 controller:: amm:: update_concentration_coef ( perp_market, concentration_coef_scale) ?;
10591076 crate :: dlog!( oracle_price) ;
10601077
@@ -1070,6 +1087,48 @@ pub fn handle_initialize_perp_market(
10701087 Ok ( ( ) )
10711088}
10721089
1090+ pub fn handle_initialize_amm_cache ( ctx : Context < InitializeAmmCache > ) -> Result < ( ) > {
1091+ let amm_cache = & mut ctx. accounts . amm_cache ;
1092+ let state = & ctx. accounts . state ;
1093+ amm_cache
1094+ . cache
1095+ . resize_with ( state. number_of_markets as usize , CacheInfo :: default) ;
1096+
1097+ Ok ( ( ) )
1098+ }
1099+
1100+ pub fn handle_update_init_amm_cache_info < ' c : ' info , ' info > (
1101+ ctx : Context < ' _ , ' _ , ' c , ' info , UpdateInitAmmCacheInfo < ' info > > ,
1102+ ) -> Result < ( ) > {
1103+ let amm_cache = & mut ctx. accounts . amm_cache ;
1104+
1105+ let AccountMaps {
1106+ perp_market_map,
1107+ spot_market_map : _,
1108+ oracle_map : _,
1109+ } = load_maps (
1110+ & mut ctx. remaining_accounts . iter ( ) . peekable ( ) ,
1111+ & MarketSet :: new ( ) ,
1112+ & MarketSet :: new ( ) ,
1113+ Clock :: get ( ) ?. slot ,
1114+ None ,
1115+ ) ?;
1116+
1117+ for ( _, perp_market_loader) in perp_market_map. 0 {
1118+ let perp_market = perp_market_loader. load ( ) ?;
1119+ let market_index = perp_market. market_index as usize ;
1120+ let cache = amm_cache. cache . get_mut ( market_index) . unwrap ( ) ;
1121+ cache. oracle = perp_market. amm . oracle ;
1122+ cache. oracle_source = u8:: from ( perp_market. amm . oracle_source ) ;
1123+ cache. last_oracle_price_twap = perp_market
1124+ . amm
1125+ . historical_oracle_data
1126+ . last_oracle_price_twap ;
1127+ }
1128+
1129+ Ok ( ( ) )
1130+ }
1131+
10731132#[ access_control(
10741133 perp_market_valid( & ctx. accounts. perp_market)
10751134) ]
@@ -3128,10 +3187,11 @@ pub fn handle_update_perp_market_paused_operations(
31283187 perp_market_valid( & ctx. accounts. perp_market)
31293188) ]
31303189pub fn handle_update_perp_market_contract_tier (
3131- ctx : Context < AdminUpdatePerpMarket > ,
3190+ ctx : Context < AdminUpdatePerpMarketContractTier > ,
31323191 contract_tier : ContractTier ,
31333192) -> Result < ( ) > {
31343193 let perp_market = & mut load_mut ! ( ctx. accounts. perp_market) ?;
3194+ let amm_cache = & mut ctx. accounts . amm_cache ;
31353195 msg ! ( "perp market {}" , perp_market. market_index) ;
31363196
31373197 msg ! (
@@ -3141,6 +3201,14 @@ pub fn handle_update_perp_market_contract_tier(
31413201 ) ;
31423202
31433203 perp_market. contract_tier = contract_tier;
3204+ let max_confidence_interval_multiplier =
3205+ perp_market. get_max_confidence_interval_multiplier ( ) ?;
3206+ amm_cache
3207+ . cache
3208+ . get_mut ( perp_market. market_index as usize )
3209+ . expect ( "value should exist for market index" )
3210+ . max_confidence_interval_multiplier = max_confidence_interval_multiplier;
3211+
31443212 Ok ( ( ) )
31453213}
31463214
@@ -3488,6 +3556,7 @@ pub fn handle_update_perp_market_oracle(
34883556 skip_invariant_check : bool ,
34893557) -> Result < ( ) > {
34903558 let perp_market = & mut load_mut ! ( ctx. accounts. perp_market) ?;
3559+ let amm_cache = & mut ctx. accounts . amm_cache ;
34913560 msg ! ( "perp market {}" , perp_market. market_index) ;
34923561
34933562 let clock = Clock :: get ( ) ?;
@@ -3566,6 +3635,14 @@ pub fn handle_update_perp_market_oracle(
35663635 perp_market. amm . oracle = oracle;
35673636 perp_market. amm . oracle_source = oracle_source;
35683637
3638+ let amm_position_cache_info = amm_cache
3639+ . cache
3640+ . get_mut ( perp_market. market_index as usize )
3641+ . expect ( "value should exist for market index" ) ;
3642+
3643+ amm_position_cache_info. oracle = oracle;
3644+ amm_position_cache_info. oracle_source = u8:: from ( oracle_source) ;
3645+
35693646 Ok ( ( ) )
35703647}
35713648
@@ -4890,12 +4967,57 @@ pub struct InitializePerpMarket<'info> {
48904967 payer = admin
48914968 ) ]
48924969 pub perp_market : AccountLoader < ' info , PerpMarket > ,
4970+ #[ account(
4971+ mut ,
4972+ seeds = [ AMM_POSITIONS_CACHE . as_ref( ) ] ,
4973+ bump,
4974+ realloc = AmmCache :: space( amm_cache. cache. len( ) + 1 as usize ) ,
4975+ realloc:: payer = admin,
4976+ realloc:: zero = false ,
4977+ ) ]
4978+ pub amm_cache : Box < Account < ' info , AmmCache > > ,
48934979 /// CHECK: checked in `initialize_perp_market`
48944980 pub oracle : AccountInfo < ' info > ,
48954981 pub rent : Sysvar < ' info , Rent > ,
48964982 pub system_program : Program < ' info , System > ,
48974983}
48984984
4985+ #[ derive( Accounts ) ]
4986+ pub struct InitializeAmmCache < ' info > {
4987+ #[ account(
4988+ mut ,
4989+ constraint = admin. key( ) == admin_hot_wallet:: id( ) || admin. key( ) == state. admin
4990+ ) ]
4991+ pub admin : Signer < ' info > ,
4992+ pub state : Box < Account < ' info , State > > ,
4993+ #[ account(
4994+ init,
4995+ seeds = [ AMM_POSITIONS_CACHE . as_ref( ) ] ,
4996+ space = AmmCache :: space( state. number_of_markets as usize ) ,
4997+ bump,
4998+ payer = admin
4999+ ) ]
5000+ pub amm_cache : Box < Account < ' info , AmmCache > > ,
5001+ pub rent : Sysvar < ' info , Rent > ,
5002+ pub system_program : Program < ' info , System > ,
5003+ }
5004+
5005+ #[ derive( Accounts ) ]
5006+ pub struct UpdateInitAmmCacheInfo < ' info > {
5007+ #[ account(
5008+ mut ,
5009+ constraint = admin. key( ) == admin_hot_wallet:: id( ) || admin. key( ) == state. admin
5010+ ) ]
5011+ pub state : Box < Account < ' info , State > > ,
5012+ pub admin : Signer < ' info > ,
5013+ #[ account(
5014+ mut ,
5015+ seeds = [ AMM_POSITIONS_CACHE . as_ref( ) ] ,
5016+ bump,
5017+ ) ]
5018+ pub amm_cache : Box < Account < ' info , AmmCache > > ,
5019+ }
5020+
48995021#[ derive( Accounts ) ]
49005022pub struct DeleteInitializedPerpMarket < ' info > {
49015023 #[ account( mut ) ]
@@ -4920,6 +5042,23 @@ pub struct AdminUpdatePerpMarket<'info> {
49205042 pub perp_market : AccountLoader < ' info , PerpMarket > ,
49215043}
49225044
5045+ #[ derive( Accounts ) ]
5046+ pub struct AdminUpdatePerpMarketContractTier < ' info > {
5047+ pub admin : Signer < ' info > ,
5048+ #[ account(
5049+ has_one = admin
5050+ ) ]
5051+ pub state : Box < Account < ' info , State > > ,
5052+ #[ account( mut ) ]
5053+ pub perp_market : AccountLoader < ' info , PerpMarket > ,
5054+ #[ account(
5055+ mut ,
5056+ seeds = [ AMM_POSITIONS_CACHE . as_ref( ) ] ,
5057+ bump,
5058+ ) ]
5059+ pub amm_cache : Box < Account < ' info , AmmCache > > ,
5060+ }
5061+
49235062#[ derive( Accounts ) ]
49245063pub struct AdminUpdatePerpMarketAmmSummaryStats < ' info > {
49255064 #[ account(
@@ -5087,6 +5226,12 @@ pub struct AdminUpdatePerpMarketOracle<'info> {
50875226 pub oracle : AccountInfo < ' info > ,
50885227 /// CHECK: checked in `admin_update_perp_market_oracle` ix constraint
50895228 pub old_oracle : AccountInfo < ' info > ,
5229+ #[ account(
5230+ mut ,
5231+ seeds = [ AMM_POSITIONS_CACHE . as_ref( ) ] ,
5232+ bump,
5233+ ) ]
5234+ pub amm_cache : Box < Account < ' info , AmmCache > > ,
50905235}
50915236
50925237#[ derive( Accounts ) ]
0 commit comments