Skip to content

Commit 8d3e848

Browse files
committed
address comments round 2
1 parent 00139c4 commit 8d3e848

File tree

17 files changed

+317
-187
lines changed

17 files changed

+317
-187
lines changed

programs/drift/src/ids.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,12 @@ pub mod titan_mainnet_argos_v1 {
122122
use solana_program::declare_id;
123123
declare_id!("T1TANpTeScyeqVzzgNViGDNrkQ6qHz9KrSBS4aNXvGT");
124124
}
125+
126+
pub const WHITELISTED_SWAP_PROGRAMS: &[solana_program::pubkey::Pubkey] = &[
127+
serum_program::id(),
128+
jupiter_mainnet_3::id(),
129+
jupiter_mainnet_4::id(),
130+
jupiter_mainnet_6::id(),
131+
dflow_mainnet_aggregator_4::id(),
132+
titan_mainnet_argos_v1::id(),
133+
];

programs/drift/src/instructions/admin.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,11 +3362,10 @@ pub fn handle_update_perp_market_paused_operations(
33623362
perp_market_valid(&ctx.accounts.perp_market)
33633363
)]
33643364
pub fn handle_update_perp_market_contract_tier(
3365-
ctx: Context<AdminUpdatePerpMarketContractTier>,
3365+
ctx: Context<AdminUpdatePerpMarket>,
33663366
contract_tier: ContractTier,
33673367
) -> Result<()> {
33683368
let perp_market = &mut load_mut!(ctx.accounts.perp_market)?;
3369-
let amm_cache = &mut ctx.accounts.amm_cache;
33703369
msg!("perp market {}", perp_market.market_index);
33713370

33723371
msg!(
@@ -3376,7 +3375,6 @@ pub fn handle_update_perp_market_contract_tier(
33763375
);
33773376

33783377
perp_market.contract_tier = contract_tier;
3379-
amm_cache.update_perp_market_fields(perp_market)?;
33803378

33813379
Ok(())
33823380
}
@@ -5556,23 +5554,6 @@ pub struct HotAdminUpdatePerpMarket<'info> {
55565554
pub perp_market: AccountLoader<'info, PerpMarket>,
55575555
}
55585556

5559-
#[derive(Accounts)]
5560-
pub struct AdminUpdatePerpMarketContractTier<'info> {
5561-
pub admin: Signer<'info>,
5562-
#[account(
5563-
has_one = admin
5564-
)]
5565-
pub state: Box<Account<'info, State>>,
5566-
#[account(mut)]
5567-
pub perp_market: AccountLoader<'info, PerpMarket>,
5568-
#[account(
5569-
mut,
5570-
seeds = [AMM_POSITIONS_CACHE.as_ref()],
5571-
bump = amm_cache.bump,
5572-
)]
5573-
pub amm_cache: Box<Account<'info, AmmCache>>,
5574-
}
5575-
55765557
#[derive(Accounts)]
55775558
pub struct AdminUpdatePerpMarketAmmSummaryStats<'info> {
55785559
#[account(

programs/drift/src/instructions/keeper.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,6 @@ pub fn handle_pause_spot_market_deposit_withdraw(
33133313
Ok(())
33143314
}
33153315

3316-
// Refactored main function
33173316
pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
33183317
ctx: Context<'_, '_, 'c, 'info, SettleAmmPnlToLp<'info>>,
33193318
) -> Result<()> {
@@ -3402,6 +3401,8 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
34023401
return Err(ErrorCode::AMMCacheStale.into());
34033402
}
34043403

3404+
quote_constituent.sync_token_balance(ctx.accounts.constituent_quote_token_account.amount);
3405+
34053406
// Create settlement context
34063407
let settlement_ctx = SettlementContext {
34073408
quote_owed_from_lp: cached_info.quote_owed_from_lp_pool,
@@ -3422,7 +3423,12 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
34223423

34233424
// Calculate settlement
34243425
let settlement_result = calculate_settlement_amount(&settlement_ctx)?;
3425-
validate_settlement_amount(&settlement_ctx, &settlement_result)?;
3426+
validate_settlement_amount(
3427+
&settlement_ctx,
3428+
&settlement_result,
3429+
&perp_market,
3430+
quote_market,
3431+
)?;
34263432

34273433
if settlement_result.direction == SettlementDirection::None {
34283434
continue;
@@ -3613,7 +3619,10 @@ pub struct SettleAmmPnlToLp<'info> {
36133619
pub state: Box<Account<'info, State>>,
36143620
#[account(mut)]
36153621
pub lp_pool: AccountLoader<'info, LPPool>,
3616-
#[account(mut)]
3622+
#[account(
3623+
mut,
3624+
constraint = keeper.key() == crate::ids::lp_pool_swap_wallet::id() || keeper.key() == admin_hot_wallet::id() || keeper.key() == state.admin.key(),
3625+
)]
36173626
pub keeper: Signer<'info>,
36183627
/// CHECK: checked in AmmCacheZeroCopy checks
36193628
#[account(mut)]

programs/drift/src/instructions/lp_admin.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::controller::token::{receive, send_from_program_vault_with_signature_seeds};
22
use crate::error::ErrorCode;
3-
use crate::ids::{admin_hot_wallet, lp_pool_swap_wallet};
3+
use crate::ids::{admin_hot_wallet, lp_pool_swap_wallet, WHITELISTED_SWAP_PROGRAMS};
44
use crate::instructions::optional_accounts::{get_token_mint, load_maps, AccountMaps};
55
use crate::math::constants::{PRICE_PRECISION_U64, QUOTE_SPOT_MARKET_INDEX};
66
use crate::math::safe_math::SafeMath;
@@ -19,15 +19,11 @@ use crate::validate;
1919
use crate::{controller, load_mut};
2020
use anchor_lang::prelude::*;
2121
use anchor_lang::Discriminator;
22-
use anchor_spl::associated_token::AssociatedToken;
2322
use anchor_spl::token::Token;
2423
use anchor_spl::token_2022::Token2022;
2524
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
2625

27-
use crate::ids::{
28-
jupiter_mainnet_3, jupiter_mainnet_4, jupiter_mainnet_6, lighthouse, marinade_mainnet,
29-
serum_program,
30-
};
26+
use crate::ids::{lighthouse, marinade_mainnet};
3127

3228
use crate::state::traits::Size;
3329
use solana_program::sysvar::instructions;
@@ -84,7 +80,7 @@ pub fn handle_initialize_lp_pool(
8480
target_oracle_delay_fee_bps_per_10_slots: 0,
8581
target_position_delay_fee_bps_per_10_slots: 0,
8682
lp_pool_id,
87-
padding: [0u8; 14],
83+
padding: [0u8; 174],
8884
whitelist_mint,
8985
};
9086

@@ -664,9 +660,6 @@ pub fn handle_begin_lp_swap<'c: 'info, 'info>(
664660
in_constituent.flash_loan_initial_token_amount = ctx.accounts.signer_in_token_account.amount;
665661
out_constituent.flash_loan_initial_token_amount = ctx.accounts.signer_out_token_account.amount;
666662

667-
// drop(in_constituent);
668-
// drop(out_constituent);
669-
670663
send_from_program_vault_with_signature_seeds(
671664
&ctx.accounts.token_program,
672665
constituent_in_token_account,
@@ -767,13 +760,7 @@ pub fn handle_begin_lp_swap<'c: 'info, 'info>(
767760
)?;
768761
}
769762
} else {
770-
let mut whitelisted_programs = vec![
771-
serum_program::id(),
772-
AssociatedToken::id(),
773-
jupiter_mainnet_3::ID,
774-
jupiter_mainnet_4::ID,
775-
jupiter_mainnet_6::ID,
776-
];
763+
let mut whitelisted_programs = WHITELISTED_SWAP_PROGRAMS.to_vec();
777764
whitelisted_programs.push(Token::id());
778765
whitelisted_programs.push(Token2022::id());
779766
whitelisted_programs.push(marinade_mainnet::ID);

programs/drift/src/instructions/user.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ use crate::controller::spot_position::{
2323
use crate::error::ErrorCode;
2424
use crate::get_then_update_id;
2525
use crate::ids::admin_hot_wallet;
26-
use crate::ids::{
27-
dflow_mainnet_aggregator_4, jupiter_mainnet_3, jupiter_mainnet_4, jupiter_mainnet_6,
28-
lighthouse, marinade_mainnet, serum_program, titan_mainnet_argos_v1,
29-
};
26+
use crate::ids::WHITELISTED_SWAP_PROGRAMS;
27+
use crate::ids::{lighthouse, marinade_mainnet};
3028
use crate::instructions::constraints::*;
3129
use crate::instructions::optional_accounts::get_revenue_share_escrow_account;
3230
use crate::instructions::optional_accounts::{
@@ -117,7 +115,6 @@ use crate::validation::whitelist::validate_whitelist_token;
117115
use crate::{controller, math};
118116
use crate::{load_mut, ExchangeStatus};
119117
use anchor_lang::solana_program::sysvar::instructions;
120-
use anchor_spl::associated_token::AssociatedToken;
121118
use borsh::{BorshDeserialize, BorshSerialize};
122119
use solana_program::sysvar::instructions::ID as IX_ID;
123120

@@ -3680,15 +3677,7 @@ pub fn handle_begin_swap<'c: 'info, 'info>(
36803677
)?;
36813678
}
36823679
} else {
3683-
let mut whitelisted_programs = vec![
3684-
serum_program::id(),
3685-
AssociatedToken::id(),
3686-
jupiter_mainnet_3::ID,
3687-
jupiter_mainnet_4::ID,
3688-
jupiter_mainnet_6::ID,
3689-
dflow_mainnet_aggregator_4::ID,
3690-
titan_mainnet_argos_v1::ID,
3691-
];
3680+
let mut whitelisted_programs = WHITELISTED_SWAP_PROGRAMS.to_vec();
36923681
if !delegate_is_signer {
36933682
whitelisted_programs.push(Token::id());
36943683
whitelisted_programs.push(Token2022::id());

programs/drift/src/lib.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ pub mod drift {
13931393
}
13941394

13951395
pub fn update_perp_market_contract_tier(
1396-
ctx: Context<AdminUpdatePerpMarketContractTier>,
1396+
ctx: Context<AdminUpdatePerpMarket>,
13971397
contract_tier: ContractTier,
13981398
) -> Result<()> {
13991399
handle_update_perp_market_contract_tier(ctx, contract_tier)
@@ -1802,24 +1802,6 @@ pub mod drift {
18021802
handle_initialize_high_leverage_mode_config(ctx, max_users)
18031803
}
18041804

1805-
pub fn initialize_lp_pool(
1806-
ctx: Context<InitializeLpPool>,
1807-
lp_pool_id: u8,
1808-
min_mint_fee: i64,
1809-
max_aum: u128,
1810-
max_settle_quote_amount_per_market: u64,
1811-
whitelist_mint: Pubkey,
1812-
) -> Result<()> {
1813-
handle_initialize_lp_pool(
1814-
ctx,
1815-
lp_pool_id,
1816-
min_mint_fee,
1817-
max_aum,
1818-
max_settle_quote_amount_per_market,
1819-
whitelist_mint,
1820-
)
1821-
}
1822-
18231805
pub fn update_high_leverage_mode_config(
18241806
ctx: Context<UpdateHighLeverageModeConfig>,
18251807
max_users: u32,
@@ -1934,6 +1916,24 @@ pub mod drift {
19341916
handle_change_approved_builder(ctx, builder, max_fee_bps, add)
19351917
}
19361918

1919+
pub fn initialize_lp_pool(
1920+
ctx: Context<InitializeLpPool>,
1921+
lp_pool_id: u8,
1922+
min_mint_fee: i64,
1923+
max_aum: u128,
1924+
max_settle_quote_amount_per_market: u64,
1925+
whitelist_mint: Pubkey,
1926+
) -> Result<()> {
1927+
handle_initialize_lp_pool(
1928+
ctx,
1929+
lp_pool_id,
1930+
min_mint_fee,
1931+
max_aum,
1932+
max_settle_quote_amount_per_market,
1933+
whitelist_mint,
1934+
)
1935+
}
1936+
19371937
pub fn update_feature_bit_flags_settle_lp_pool(
19381938
ctx: Context<HotAdminUpdateState>,
19391939
enable: bool,

programs/drift/src/math/lp_pool.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ pub mod perp_lp_pool_settlement {
55
use crate::error::ErrorCode;
66
use crate::math::casting::Cast;
77
use crate::math::constants::QUOTE_PRECISION_U64;
8-
use crate::state::spot_market::SpotBalanceType;
8+
use crate::math::spot_balance::get_token_amount;
9+
use crate::state::spot_market::{SpotBalance, SpotBalanceType};
910
use crate::{
1011
math::safe_math::SafeMath,
1112
state::{amm_cache::CacheInfo, perp_market::PerpMarket, spot_market::SpotMarket},
@@ -55,6 +56,8 @@ pub mod perp_lp_pool_settlement {
5556
pub fn validate_settlement_amount(
5657
ctx: &SettlementContext,
5758
result: &SettlementResult,
59+
perp_market: &PerpMarket,
60+
quote_spot_market: &SpotMarket,
5861
) -> Result<()> {
5962
if result.amount_transferred > ctx.max_settle_quote_amount {
6063
msg!(
@@ -64,6 +67,49 @@ pub mod perp_lp_pool_settlement {
6467
);
6568
return Err(ErrorCode::LpPoolSettleInvariantBreached.into());
6669
}
70+
71+
if result.direction == SettlementDirection::ToLpPool {
72+
if result.fee_pool_used > 0 {
73+
let fee_pool_token_amount = get_token_amount(
74+
perp_market.amm.fee_pool.balance(),
75+
quote_spot_market,
76+
&SpotBalanceType::Deposit,
77+
)?;
78+
validate!(
79+
fee_pool_token_amount >= result.fee_pool_used,
80+
ErrorCode::LpPoolSettleInvariantBreached.into(),
81+
"Fee pool balance insufficient for settlement: {} < {}",
82+
fee_pool_token_amount,
83+
result.fee_pool_used
84+
)?;
85+
}
86+
87+
if result.pnl_pool_used > 0 {
88+
let pnl_pool_token_amount = get_token_amount(
89+
perp_market.pnl_pool.balance(),
90+
quote_spot_market,
91+
&SpotBalanceType::Deposit,
92+
)?;
93+
validate!(
94+
pnl_pool_token_amount >= result.pnl_pool_used,
95+
ErrorCode::LpPoolSettleInvariantBreached.into(),
96+
"Pnl pool balance insufficient for settlement: {} < {}",
97+
pnl_pool_token_amount,
98+
result.pnl_pool_used
99+
)?;
100+
}
101+
}
102+
if result.direction == SettlementDirection::FromLpPool {
103+
validate!(
104+
ctx.quote_constituent_token_balance
105+
.saturating_sub(result.amount_transferred)
106+
>= QUOTE_PRECISION_U64,
107+
ErrorCode::LpPoolSettleInvariantBreached.into(),
108+
"Quote constituent token balance insufficient for settlement: {} < {}",
109+
ctx.quote_constituent_token_balance,
110+
result.amount_transferred
111+
)?;
112+
}
67113
Ok(())
68114
}
69115

programs/drift/src/state/amm_cache.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,16 +285,6 @@ impl<'a> AccountZeroCopyMut<'a, CacheInfo, AmmCacheFixed> {
285285
perp_market: &PerpMarket,
286286
quote_market: &SpotMarket,
287287
) -> DriftResult<()> {
288-
if perp_market.lp_fee_transfer_scalar == 0
289-
&& perp_market.lp_exchange_fee_excluscion_scalar == 0
290-
{
291-
msg!(
292-
"lp_fee_transfer_scalar and lp_net_pnl_transfer_scalar are 0 for perp market {}. not updating quote amount owed in cache",
293-
perp_market.market_index
294-
);
295-
return Ok(());
296-
}
297-
298288
let cached_info = self.get_mut(perp_market.market_index as u32);
299289

300290
let fee_pool_token_amount = get_token_amount(

0 commit comments

Comments
 (0)