Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions programs/drift/src/instructions/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4732,20 +4732,23 @@ pub fn handle_initialize_lp_pool(
};

let amm_constituent_mapping = &mut ctx.accounts.amm_constituent_mapping;
amm_constituent_mapping.lp_pool = ctx.accounts.lp_pool.key();
amm_constituent_mapping.bump = ctx.bumps.amm_constituent_mapping;
amm_constituent_mapping
.weights
.resize_with(0 as usize, AmmConstituentDatum::default);
amm_constituent_mapping.validate()?;

let constituent_target_base = &mut ctx.accounts.constituent_target_base;
constituent_target_base.lp_pool = ctx.accounts.lp_pool.key();
constituent_target_base.bump = ctx.bumps.constituent_target_base;
constituent_target_base
.targets
.resize_with(0 as usize, TargetsDatum::default);
constituent_target_base.validate()?;

let consituent_correlations = &mut ctx.accounts.constituent_correlations;
consituent_correlations.lp_pool = ctx.accounts.lp_pool.key();
consituent_correlations.bump = ctx.bumps.constituent_correlations;
consituent_correlations.correlations.resize(0 as usize, 0);
consituent_correlations.validate()?;
Expand Down Expand Up @@ -5005,6 +5008,7 @@ pub fn handle_initialize_constituent<'info>(
oracle_staleness_threshold: u64,
cost_to_trade_bps: i32,
constituent_derivative_index: Option<i16>,
constituent_derivative_depeg_threshold: u64,
derivative_weight: u64,
volatility: u64,
gamma_execution: u8,
Expand Down Expand Up @@ -5056,6 +5060,7 @@ pub fn handle_initialize_constituent<'info>(
constituent.constituent_index = (constituent_target_base.targets.len() - 1) as u16;
constituent.next_swap_id = 1;
constituent.constituent_derivative_index = constituent_derivative_index.unwrap_or(-1);
constituent.constituent_derivative_depeg_threshold = constituent_derivative_depeg_threshold;
constituent.derivative_weight = derivative_weight;
constituent.volatility = volatility;
constituent.gamma_execution = gamma_execution;
Expand Down
4 changes: 1 addition & 3 deletions programs/drift/src/instructions/keeper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ use crate::math::constants::QUOTE_PRECISION;
use crate::math::constants::QUOTE_SPOT_MARKET_INDEX;
use crate::math::constants::SPOT_BALANCE_PRECISION;
use crate::math::margin::{calculate_user_equity, meets_settle_pnl_maintenance_margin_requirement};
use crate::math::oracle::is_oracle_valid_for_action;
use crate::math::oracle::DriftAction;
use crate::math::orders::{estimate_price_from_side, find_bids_and_asks_from_users};
use crate::math::position::calculate_base_asset_value_and_pnl_with_oracle_price;
use crate::math::safe_math::SafeMath;
Expand Down Expand Up @@ -3311,7 +3309,7 @@ pub struct UpdateAmmCache<'info> {
pub amm_cache: AccountInfo<'info>,
#[account(
owner = crate::ID,
seeds = [b"spot_market", 0_u16.to_le_bytes().as_ref()],
seeds = [b"spot_market", QUOTE_SPOT_MARKET_INDEX.to_le_bytes().as_ref()],
bump,
)]
pub quote_market: AccountLoader<'info, SpotMarket>,
Expand Down
133 changes: 39 additions & 94 deletions programs/drift/src/instructions/lp_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};

use crate::{
controller::{
self, lp,
self,
spot_balance::update_spot_balances,
token::{burn_tokens, mint_tokens},
},
Expand All @@ -16,7 +16,7 @@ use crate::{
self,
casting::Cast,
constants::{
BASE_PRECISION_I128, PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_I64,
PERCENTAGE_PRECISION, PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_I64,
PERCENTAGE_PRECISION_U64, PRICE_PRECISION_I128, QUOTE_PRECISION_I128,
},
oracle::{is_oracle_valid_for_action, oracle_validity, DriftAction},
Expand All @@ -25,13 +25,12 @@ use crate::{
math_error, msg, safe_decrement, safe_increment,
state::{
constituent_map::{ConstituentMap, ConstituentSet},
events::{LPMintRedeemRecord, LPSwapRecord},
events::{emit_stack, LPMintRedeemRecord, LPSwapRecord},
lp_pool::{
calculate_target_weight, AmmConstituentDatum, AmmConstituentMappingFixed, Constituent,
ConstituentCorrelationsFixed, ConstituentTargetBaseFixed, LPPool, TargetsDatum,
WeightValidationFlags, CONSTITUENT_CORRELATIONS_PDA_SEED,
LP_POOL_SWAP_AUM_UPDATE_DELAY, MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC,
MAX_CONSTITUENT_ORACLE_SLOT_STALENESS_FOR_AUM,
WeightValidationFlags, LP_POOL_SWAP_AUM_UPDATE_DELAY,
MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC, MAX_CONSTITUENT_ORACLE_SLOT_STALENESS_FOR_AUM,
},
oracle::OraclePriceData,
oracle_map::OracleMap,
Expand All @@ -40,6 +39,7 @@ use crate::{
spot_market::{SpotBalanceType, SpotMarket},
spot_market_map::get_writable_spot_market_set_from_many,
state::State,
traits::Size,
user::MarketType,
zero_copy::{AccountZeroCopy, AccountZeroCopyMut, ZeroCopyLoader},
},
Expand All @@ -53,16 +53,14 @@ use crate::controller::spot_balance::update_spot_market_cumulative_interest;
use crate::controller::token::{receive, send_from_program_vault};
use crate::instructions::constraints::*;
use crate::state::lp_pool::{
AMM_MAP_PDA_SEED, CONSTITUENT_PDA_SEED, CONSTITUENT_TARGET_BASE_PDA_SEED,
LP_POOL_TOKEN_VAULT_PDA_SEED,
CONSTITUENT_PDA_SEED, CONSTITUENT_TARGET_BASE_PDA_SEED, LP_POOL_TOKEN_VAULT_PDA_SEED,
};

pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, UpdateConstituentTargetBase<'info>>,
) -> Result<()> {
let slot = Clock::get()?.slot;

let lp_pool = &ctx.accounts.lp_pool.load()?;
let lp_pool_key: &Pubkey = &ctx.accounts.lp_pool.key();
let amm_cache_key: &Pubkey = &ctx.accounts.amm_cache.key();

Expand All @@ -87,29 +85,15 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
)?;

let state = &ctx.accounts.state;
let constituent_target_base_key = &ctx.accounts.constituent_target_base.key();
let amm_mapping_key = &ctx.accounts.amm_constituent_mapping.key();

let mut constituent_target_base: AccountZeroCopyMut<
'_,
TargetsDatum,
ConstituentTargetBaseFixed,
> = ctx.accounts.constituent_target_base.load_zc_mut()?;

let bump = constituent_target_base.fixed.bump;
let expected_pda = &Pubkey::create_program_address(
&[
CONSTITUENT_TARGET_BASE_PDA_SEED.as_ref(),
lp_pool.pubkey.as_ref(),
bump.to_le_bytes().as_ref(),
],
&crate::ID,
)
.map_err(|_| ErrorCode::InvalidPDA)?;
validate!(
expected_pda.eq(constituent_target_base_key),
constituent_target_base.fixed.lp_pool.eq(lp_pool_key),
ErrorCode::InvalidPDA,
"Constituent target weights PDA does not match expected PDA"
"Constituent target base lp pool pubkey does not match lp pool pubkey",
)?;

let num_constituents = constituent_target_base.len();
Expand All @@ -124,24 +108,18 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
AmmConstituentDatum,
AmmConstituentMappingFixed,
> = ctx.accounts.amm_constituent_mapping.load_zc()?;

let amm_mapping_bump = amm_constituent_mapping.fixed.bump;
let expected_map_pda = &Pubkey::create_program_address(
&[
AMM_MAP_PDA_SEED.as_ref(),
lp_pool.pubkey.as_ref(),
amm_mapping_bump.to_le_bytes().as_ref(),
],
&crate::ID,
)
.map_err(|_| ErrorCode::InvalidPDA)?;
validate!(
expected_map_pda.eq(amm_mapping_key),
amm_constituent_mapping.fixed.lp_pool.eq(lp_pool_key),
ErrorCode::InvalidPDA,
"Amm mapping PDA does not match expected PDA"
"Amm constituent mapping lp pool pubkey does not match lp pool pubkey",
)?;

let mut amm_inventories: Vec<(u16, i64, i64)> = vec![];
let remaining_accounts = &mut ctx.remaining_accounts.iter().peekable();
let constituent_map =
ConstituentMap::load(&ConstituentSet::new(), &lp_pool_key, remaining_accounts)?;

let mut amm_inventories: Vec<(u16, i64, i64)> =
Vec::with_capacity(amm_constituent_mapping.len() as usize);
for (_, datum) in amm_constituent_mapping.iter().enumerate() {
let cache_info = amm_cache.get(datum.perp_market_index as u32);

Expand Down Expand Up @@ -183,11 +161,8 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
return Ok(());
}

let remaining_accounts = &mut ctx.remaining_accounts.iter().peekable();
let constituent_map =
ConstituentMap::load(&ConstituentSet::new(), &lp_pool_key, remaining_accounts)?;

let mut constituent_indexes_and_decimals_and_prices: Vec<(u16, u8, i64)> = vec![];
let mut constituent_indexes_and_decimals_and_prices: Vec<(u16, u8, i64)> =
Vec::with_capacity(constituent_map.0.len());
for (index, loader) in &constituent_map.0 {
let constituent_ref = loader.load()?;
constituent_indexes_and_decimals_and_prices.push((
Expand Down Expand Up @@ -248,25 +223,15 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
"Constituent map length does not match lp pool constituent count"
)?;

let constituent_target_base_key = &ctx.accounts.constituent_target_base.key();
let mut constituent_target_base: AccountZeroCopyMut<
'_,
TargetsDatum,
ConstituentTargetBaseFixed,
> = ctx.accounts.constituent_target_base.load_zc_mut()?;
let expected_pda = &Pubkey::create_program_address(
&[
CONSTITUENT_TARGET_BASE_PDA_SEED.as_ref(),
lp_pool.pubkey.as_ref(),
constituent_target_base.fixed.bump.to_le_bytes().as_ref(),
],
&crate::ID,
)
.map_err(|_| ErrorCode::InvalidPDA)?;
validate!(
expected_pda.eq(constituent_target_base_key),
constituent_target_base.fixed.lp_pool.eq(&lp_pool.pubkey),
ErrorCode::InvalidPDA,
"Constituent target weights PDA does not match expected PDA"
"Constituent target base lp pool pubkey does not match lp pool pubkey",
)?;

let amm_cache_key: &Pubkey = &ctx.accounts.amm_cache.key();
Expand Down Expand Up @@ -417,8 +382,8 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
if constituent.last_oracle_price
< parent_constituent
.last_oracle_price
.safe_mul(9)?
.safe_div(10)?
.safe_mul(constituent.constituent_derivative_depeg_threshold as i64)?
.safe_div(PERCENTAGE_PRECISION_I64)?
{
msg!(
"Constituent {} last oracle price {} is too low compared to parent constituent {} last oracle price {}. Assuming depegging and setting target base to 0.",
Expand Down Expand Up @@ -504,40 +469,20 @@ pub fn handle_lp_pool_swap<'c: 'info, 'info>(
let mut in_constituent = ctx.accounts.in_constituent.load_mut()?;
let mut out_constituent = ctx.accounts.out_constituent.load_mut()?;

let constituent_target_base_key = &ctx.accounts.constituent_target_base.key();
let constituent_target_base: AccountZeroCopy<'_, TargetsDatum, ConstituentTargetBaseFixed> =
ctx.accounts.constituent_target_base.load_zc()?;
let expected_pda = &Pubkey::create_program_address(
&[
CONSTITUENT_TARGET_BASE_PDA_SEED.as_ref(),
lp_pool.pubkey.as_ref(),
constituent_target_base.fixed.bump.to_le_bytes().as_ref(),
],
&crate::ID,
)
.map_err(|_| ErrorCode::InvalidPDA)?;
validate!(
expected_pda.eq(constituent_target_base_key),
constituent_target_base.fixed.lp_pool.eq(&lp_pool.pubkey),
ErrorCode::InvalidPDA,
"Constituent target weights PDA does not match expected PDA"
"Constituent target base lp pool pubkey does not match lp pool pubkey",
)?;

let constituent_correlation_key = &ctx.accounts.constituent_correlations.key();
let constituent_correlations: AccountZeroCopy<'_, i64, ConstituentCorrelationsFixed> =
ctx.accounts.constituent_correlations.load_zc()?;
let expected_correlation_pda = &Pubkey::create_program_address(
&[
CONSTITUENT_CORRELATIONS_PDA_SEED.as_ref(),
lp_pool.pubkey.as_ref(),
constituent_correlations.fixed.bump.to_le_bytes().as_ref(),
],
&crate::ID,
)
.map_err(|_| ErrorCode::InvalidPDA)?;
validate!(
expected_correlation_pda.eq(constituent_correlation_key),
constituent_correlations.fixed.lp_pool.eq(&lp_pool.pubkey),
ErrorCode::InvalidPDA,
"Constituent correlations PDA does not match expected PDA"
"Constituent correlations lp pool pubkey does not match lp pool pubkey",
)?;

let AccountMaps {
Expand Down Expand Up @@ -665,7 +610,7 @@ pub fn handle_lp_pool_swap<'c: 'info, 'info>(
let in_swap_id = get_then_update_id!(in_constituent, next_swap_id);
let out_swap_id = get_then_update_id!(out_constituent, next_swap_id);

emit!(LPSwapRecord {
emit_stack::<_, { LPSwapRecord::SIZE }>(LPSwapRecord {
ts: now,
slot,
authority: ctx.accounts.authority.key(),
Expand All @@ -687,19 +632,19 @@ pub fn handle_lp_pool_swap<'c: 'info, 'info>(
in_oracle.price,
&in_spot_market,
0,
lp_pool.last_aum
lp_pool.last_aum,
)?,
in_market_target_weight: in_target_weight,
out_market_current_weight: out_constituent.get_weight(
out_oracle.price,
&out_spot_market,
0,
lp_pool.last_aum
lp_pool.last_aum,
)?,
out_market_target_weight: out_target_weight,
in_swap_id,
out_swap_id,
});
})?;

receive(
&ctx.accounts.token_program,
Expand Down Expand Up @@ -896,11 +841,11 @@ pub fn handle_lp_pool_add_liquidity<'c: 'info, 'info>(
};

let mint_redeem_id = get_then_update_id!(lp_pool, next_mint_redeem_id);
emit!(LPMintRedeemRecord {
emit_stack::<_, { LPMintRedeemRecord::SIZE }>(LPMintRedeemRecord {
ts: now,
slot,
authority: ctx.accounts.authority.key(),
is_minting: true,
description: 1,
amount: in_amount,
fee: in_fee_amount,
spot_market_index: in_market_index,
Expand All @@ -918,10 +863,10 @@ pub fn handle_lp_pool_add_liquidity<'c: 'info, 'info>(
in_oracle.price,
&in_spot_market,
0,
lp_pool.last_aum
lp_pool.last_aum,
)?,
in_market_target_weight: in_target_weight,
});
})?;

Ok(())
}
Expand Down Expand Up @@ -1093,11 +1038,11 @@ pub fn handle_lp_pool_remove_liquidity<'c: 'info, 'info>(
};

let mint_redeem_id = get_then_update_id!(lp_pool, next_mint_redeem_id);
emit!(LPMintRedeemRecord {
emit_stack::<_, { LPMintRedeemRecord::SIZE }>(LPMintRedeemRecord {
ts: now,
slot,
authority: ctx.accounts.authority.key(),
is_minting: false,
description: 0,
amount: out_amount,
fee: out_fee_amount,
spot_market_index: out_market_index,
Expand All @@ -1115,10 +1060,10 @@ pub fn handle_lp_pool_remove_liquidity<'c: 'info, 'info>(
out_oracle.price,
&out_spot_market,
0,
lp_pool.last_aum
lp_pool.last_aum,
)?,
in_market_target_weight: out_target_weight,
});
})?;

Ok(())
}
Expand Down
1 change: 0 additions & 1 deletion programs/drift/src/instructions/optional_accounts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::error::{DriftResult, ErrorCode};
use crate::state::constituent_map::ConstituentSet;
use crate::state::high_leverage_mode_config::HighLeverageModeConfig;
use std::cell::RefMut;
use std::convert::TryFrom;
Expand Down
2 changes: 2 additions & 0 deletions programs/drift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,7 @@ pub mod drift {
oracle_staleness_threshold: u64,
cost_to_trade: i32,
constituent_derivative_index: Option<i16>,
constituent_derivative_depeg_threshold: u64,
derivative_weight: u64,
volatility: u64,
gamma_execution: u8,
Expand All @@ -1837,6 +1838,7 @@ pub mod drift {
oracle_staleness_threshold,
cost_to_trade,
constituent_derivative_index,
constituent_derivative_depeg_threshold,
derivative_weight,
volatility,
gamma_execution,
Expand Down
Loading