Skip to content

Commit eecbe20

Browse files
authored
Merge pull request #1888 from drift-labs/nour/vamm-cache-percent
add vamm cache percent scalar (default is 100)
2 parents 5cef2f8 + 03b22b8 commit eecbe20

File tree

8 files changed

+197
-139
lines changed

8 files changed

+197
-139
lines changed

programs/drift/src/instructions/admin.rs

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,84 +1114,6 @@ pub fn handle_initialize_amm_cache(ctx: Context<InitializeAmmCache>) -> Result<(
11141114
Ok(())
11151115
}
11161116

1117-
pub fn handle_update_initial_amm_cache_info<'c: 'info, 'info>(
1118-
ctx: Context<'_, '_, 'c, 'info, UpdateInitialAmmCacheInfo<'info>>,
1119-
) -> Result<()> {
1120-
let amm_cache = &mut ctx.accounts.amm_cache;
1121-
let slot = Clock::get()?.slot;
1122-
let state = &ctx.accounts.state;
1123-
1124-
let AccountMaps {
1125-
perp_market_map,
1126-
spot_market_map: _,
1127-
mut oracle_map,
1128-
} = load_maps(
1129-
&mut ctx.remaining_accounts.iter().peekable(),
1130-
&MarketSet::new(),
1131-
&MarketSet::new(),
1132-
Clock::get()?.slot,
1133-
None,
1134-
)?;
1135-
1136-
for (_, perp_market_loader) in perp_market_map.0 {
1137-
let perp_market = perp_market_loader.load()?;
1138-
let oracle_data = oracle_map.get_price_data(&perp_market.oracle_id())?;
1139-
let mm_oracle_data = perp_market.get_mm_oracle_price_data(
1140-
*oracle_data,
1141-
slot,
1142-
&ctx.accounts.state.oracle_guard_rails.validity,
1143-
)?;
1144-
1145-
amm_cache.update_perp_market_fields(&perp_market)?;
1146-
amm_cache.update_oracle_info(
1147-
slot,
1148-
perp_market.market_index,
1149-
&mm_oracle_data,
1150-
&perp_market,
1151-
&state.oracle_guard_rails,
1152-
)?;
1153-
}
1154-
1155-
Ok(())
1156-
}
1157-
#[derive(Debug, Clone, Copy, AnchorSerialize, AnchorDeserialize, PartialEq, Eq)]
1158-
pub struct OverrideAmmCacheParams {
1159-
pub quote_owed_from_lp_pool: Option<i64>,
1160-
pub last_settle_slot: Option<u64>,
1161-
pub last_fee_pool_token_amount: Option<u128>,
1162-
pub last_net_pnl_pool_token_amount: Option<i128>,
1163-
}
1164-
1165-
pub fn handle_override_amm_cache_info<'c: 'info, 'info>(
1166-
ctx: Context<'_, '_, 'c, 'info, UpdateInitialAmmCacheInfo<'info>>,
1167-
market_index: u16,
1168-
override_params: OverrideAmmCacheParams,
1169-
) -> Result<()> {
1170-
let amm_cache = &mut ctx.accounts.amm_cache;
1171-
1172-
let cache_entry = amm_cache.cache.get_mut(market_index as usize);
1173-
if cache_entry.is_none() {
1174-
msg!("No cache entry found for market index {}", market_index);
1175-
return Ok(());
1176-
}
1177-
1178-
let cache_entry = cache_entry.unwrap();
1179-
if let Some(quote_owed_from_lp_pool) = override_params.quote_owed_from_lp_pool {
1180-
cache_entry.quote_owed_from_lp_pool = quote_owed_from_lp_pool;
1181-
}
1182-
if let Some(last_settle_slot) = override_params.last_settle_slot {
1183-
cache_entry.last_settle_slot = last_settle_slot;
1184-
}
1185-
if let Some(last_fee_pool_token_amount) = override_params.last_fee_pool_token_amount {
1186-
cache_entry.last_fee_pool_token_amount = last_fee_pool_token_amount;
1187-
}
1188-
if let Some(last_net_pnl_pool_token_amount) = override_params.last_net_pnl_pool_token_amount {
1189-
cache_entry.last_net_pnl_pool_token_amount = last_net_pnl_pool_token_amount;
1190-
}
1191-
1192-
Ok(())
1193-
}
1194-
11951117
#[access_control(
11961118
perp_market_valid(&ctx.accounts.perp_market)
11971119
)]
@@ -5421,22 +5343,6 @@ pub struct InitializeAmmCache<'info> {
54215343
pub system_program: Program<'info, System>,
54225344
}
54235345

5424-
#[derive(Accounts)]
5425-
pub struct UpdateInitialAmmCacheInfo<'info> {
5426-
#[account(
5427-
mut,
5428-
constraint = admin.key() == admin_hot_wallet::id() || admin.key() == state.admin
5429-
)]
5430-
pub state: Box<Account<'info, State>>,
5431-
pub admin: Signer<'info>,
5432-
#[account(
5433-
mut,
5434-
seeds = [AMM_POSITIONS_CACHE.as_ref()],
5435-
bump = amm_cache.bump,
5436-
)]
5437-
pub amm_cache: Box<Account<'info, AmmCache>>,
5438-
}
5439-
54405346
#[derive(Accounts)]
54415347
pub struct DeleteInitializedPerpMarket<'info> {
54425348
#[account(mut)]

programs/drift/src/instructions/lp_admin.rs

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
use crate::state::perp_market_map::MarketSet;
12
use crate::{controller, load_mut};
23
use crate::controller::token::{receive, send_from_program_vault_with_signature_seeds};
34
use crate::error::ErrorCode;
45
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};
67
use crate::math::constants::{PRICE_PRECISION_U64, QUOTE_SPOT_MARKET_INDEX};
78
use crate::math::safe_math::SafeMath;
8-
use crate::state::amm_cache::AmmCache;
9+
use crate::state::amm_cache::{AmmCache, AMM_POSITIONS_CACHE};
910
use crate::state::lp_pool::{
1011
AmmConstituentDatum, AmmConstituentMapping, Constituent, ConstituentCorrelations,
1112
ConstituentTargetBase, LPPool, TargetsDatum, AMM_MAP_PDA_SEED,
@@ -896,6 +897,90 @@ pub fn handle_update_perp_market_lp_pool_status(
896897
Ok(())
897898
}
898899

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+
899984
#[derive(Accounts)]
900985
#[instruction(
901986
name: [u8; 32],
@@ -1252,6 +1337,23 @@ pub struct UpdatePerpMarketLpPoolStatus<'info> {
12521337
pub state: Box<Account<'info, State>>,
12531338
#[account(mut)]
12541339
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+
)]
12561358
pub amm_cache: Box<Account<'info, AmmCache>>,
12571359
}

programs/drift/src/instructions/lp_pool.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,14 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
129129
}
130130

131131
amm_inventories.push(AmmInventoryAndPrices {
132-
inventory: cache_info.position,
132+
inventory: cache_info
133+
.position
134+
.safe_mul(cache_info.amm_position_scalar as i64)?
135+
.safe_div(100)?,
133136
price: cache_info.oracle_price,
134137
});
135138
}
139+
msg!("amm inventories: {:?}", amm_inventories);
136140

137141
if amm_inventories.is_empty() {
138142
msg!("No valid inventories found for constituent target weights update");

programs/drift/src/state/amm_cache.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ pub struct CacheInfo {
5555
pub oracle_source: u8,
5656
pub oracle_validity: u8,
5757
pub lp_status_for_perp_market: u8,
58-
pub _padding: [u8; 13],
58+
pub amm_position_scalar: u8,
59+
pub _padding: [u8; 12],
5960
}
6061

6162
impl Size for CacheInfo {
@@ -82,7 +83,8 @@ impl Default for CacheInfo {
8283
oracle_source: 0u8,
8384
quote_owed_from_lp_pool: 0i64,
8485
lp_status_for_perp_market: 0u8,
85-
_padding: [0u8; 13],
86+
amm_position_scalar: 100u8,
87+
_padding: [0u8; 12],
8688
}
8789
}
8890
}

programs/drift/src/state/lp_pool.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,7 @@ pub fn calculate_target_weight(
11871187
}
11881188

11891189
/// Update target base based on amm_inventory and mapping
1190+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11901191
pub struct AmmInventoryAndPrices {
11911192
pub inventory: i64,
11921193
pub price: i64,

sdk/src/adminClient.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,7 @@ export class AdminClient extends DriftClient {
712712
lastSettleTs?: BN;
713713
lastFeePoolTokenAmount?: BN;
714714
lastNetPnlPoolTokenAmount?: BN;
715+
ammPositionScalar?: number;
715716
},
716717
txParams?: TxParams
717718
): Promise<TransactionSignature> {
@@ -730,20 +731,22 @@ export class AdminClient extends DriftClient {
730731
perpMarketIndex: number,
731732
params: {
732733
quoteOwedFromLpPool?: BN;
733-
lastSettleTs?: BN;
734+
lastSettleSlot?: BN;
734735
lastFeePoolTokenAmount?: BN;
735736
lastNetPnlPoolTokenAmount?: BN;
737+
ammPositionScalar?: number;
736738
}
737739
): Promise<TransactionInstruction> {
738-
return await this.program.instruction.overrideAmmCacheInfo(
740+
return this.program.instruction.overrideAmmCacheInfo(
739741
perpMarketIndex,
740742
Object.assign(
741743
{},
742744
{
743745
quoteOwedFromLpPool: null,
744-
lastSettleTs: null,
746+
lastSettleSlot: null,
745747
lastFeePoolTokenAmount: null,
746748
lastNetPnlPoolTokenAmount: null,
749+
ammPositionScalar: null,
747750
},
748751
params
749752
),

0 commit comments

Comments
 (0)