Skip to content

Commit 464e1d3

Browse files
Nour/address more comments (#1726)
* use oracle staleness threshold for staleness * add spot market vault invariant
1 parent c5ccdea commit 464e1d3

File tree

6 files changed

+30
-42
lines changed

6 files changed

+30
-42
lines changed

programs/drift/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,8 @@ pub enum ErrorCode {
662662
LpPoolAumDelayed,
663663
#[msg("Constituent oracle is stale")]
664664
ConstituentOracleStale,
665+
#[msg("LP Invariant failed")]
666+
LpInvariantFailed,
665667
}
666668

667669
#[macro_export]

programs/drift/src/instructions/lp_pool.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
casting::Cast,
1818
constants::{
1919
PERCENTAGE_PRECISION, PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_I64,
20-
PERCENTAGE_PRECISION_U64, PRICE_PRECISION_I128, QUOTE_PRECISION_I128,
20+
PERCENTAGE_PRECISION_U64, PRICE_PRECISION, PRICE_PRECISION_I128, QUOTE_PRECISION_I128,
2121
},
2222
oracle::{is_oracle_valid_for_action, oracle_validity, DriftAction},
2323
safe_math::SafeMath,
@@ -30,7 +30,7 @@ use crate::{
3030
calculate_target_weight, AmmConstituentDatum, AmmConstituentMappingFixed, Constituent,
3131
ConstituentCorrelationsFixed, ConstituentTargetBaseFixed, LPPool, TargetsDatum,
3232
WeightValidationFlags, LP_POOL_SWAP_AUM_UPDATE_DELAY,
33-
MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC, MAX_CONSTITUENT_ORACLE_SLOT_STALENESS_FOR_AUM,
33+
MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC,
3434
},
3535
oracle::OraclePriceData,
3636
oracle_map::OracleMap,
@@ -258,7 +258,7 @@ pub fn handle_update_lp_pool_aum<'c: 'info, 'info>(
258258
for i in 0..lp_pool.constituents as usize {
259259
let constituent = constituent_map.get_ref(&(i as u16))?;
260260
if slot.saturating_sub(constituent.last_oracle_slot)
261-
> MAX_CONSTITUENT_ORACLE_SLOT_STALENESS_FOR_AUM
261+
> constituent.oracle_staleness_threshold
262262
{
263263
msg!(
264264
"Constituent {} oracle slot is too stale: {}, current slot: {}",
@@ -490,13 +490,13 @@ pub fn handle_lp_pool_swap<'c: 'info, 'info>(
490490
} = load_maps(
491491
&mut ctx.remaining_accounts.iter().peekable(),
492492
&MarketSet::new(),
493-
&get_writable_spot_market_set_from_many(vec![in_market_index, out_market_index]),
493+
&MarketSet::new(),
494494
slot,
495495
Some(state.oracle_guard_rails),
496496
)?;
497497

498-
let mut in_spot_market = spot_market_map.get_ref_mut(&in_market_index)?;
499-
let mut out_spot_market = spot_market_map.get_ref_mut(&out_market_index)?;
498+
let in_spot_market = spot_market_map.get_ref(&in_market_index)?;
499+
let out_spot_market = spot_market_map.get_ref(&out_market_index)?;
500500

501501
let in_oracle_id = in_spot_market.oracle_id();
502502
let out_oracle_id = out_spot_market.oracle_id();
@@ -538,9 +538,6 @@ pub fn handle_lp_pool_swap<'c: 'info, 'info>(
538538
return Err(ErrorCode::InvalidOracle.into());
539539
}
540540

541-
update_spot_market_cumulative_interest(&mut in_spot_market, Some(&in_oracle), now)?;
542-
update_spot_market_cumulative_interest(&mut out_spot_market, Some(&out_oracle), now)?;
543-
544541
let in_target_weight = constituent_target_base.get_target_weight(
545542
in_constituent.constituent_index,
546543
&in_spot_market,
@@ -622,8 +619,6 @@ pub fn handle_lp_pool_swap<'c: 'info, 'info>(
622619
in_constituent_index: in_constituent.constituent_index,
623620
out_oracle_price: out_oracle.price,
624621
in_oracle_price: in_oracle.price,
625-
out_mint: out_constituent.mint,
626-
in_mint: in_constituent.mint,
627622
last_aum: lp_pool.last_aum,
628623
last_aum_slot: lp_pool.last_aum_slot,
629624
in_market_current_weight: in_constituent.get_weight(
@@ -833,7 +828,10 @@ pub fn handle_lp_pool_add_liquidity<'c: 'info, 'info>(
833828

834829
let dlp_total_supply = ctx.accounts.lp_mint.supply;
835830
let lp_price = if dlp_total_supply > 0 {
836-
lp_pool.last_aum.safe_div(dlp_total_supply as u128)?
831+
lp_pool
832+
.last_aum
833+
.safe_mul(PRICE_PRECISION)?
834+
.safe_div(dlp_total_supply as u128)?
837835
} else {
838836
0
839837
};
@@ -850,7 +848,6 @@ pub fn handle_lp_pool_add_liquidity<'c: 'info, 'info>(
850848
constituent_index: in_constituent.constituent_index,
851849
oracle_price: in_oracle.price,
852850
mint: in_constituent.mint,
853-
lp_mint: lp_pool.mint,
854851
lp_amount,
855852
lp_fee: lp_fee_amount,
856853
lp_price,
@@ -1032,7 +1029,10 @@ pub fn handle_lp_pool_remove_liquidity<'c: 'info, 'info>(
10321029

10331030
let dlp_total_supply = ctx.accounts.lp_mint.supply;
10341031
let lp_price = if dlp_total_supply > 0 {
1035-
lp_pool.last_aum.safe_div(dlp_total_supply as u128)?
1032+
lp_pool
1033+
.last_aum
1034+
.safe_mul(PRICE_PRECISION)?
1035+
.safe_div(dlp_total_supply as u128)?
10361036
} else {
10371037
0
10381038
};
@@ -1049,7 +1049,6 @@ pub fn handle_lp_pool_remove_liquidity<'c: 'info, 'info>(
10491049
constituent_index: out_constituent.constituent_index,
10501050
oracle_price: out_oracle.price,
10511051
mint: out_constituent.mint,
1052-
lp_mint: lp_pool.mint,
10531052
lp_amount: lp_burn_amount,
10541053
lp_fee: lp_fee_amount,
10551054
lp_price,
@@ -1112,6 +1111,8 @@ pub fn handle_deposit_to_program_vault<'c: 'info, 'info>(
11121111
return Err(ErrorCode::InsufficientDeposit.into());
11131112
}
11141113

1114+
let deposit_plus_token_amount_before = amount.safe_add(spot_market_vault.amount)?;
1115+
11151116
let oracle_data = oracle_map.get_price_data(&oracle_id)?;
11161117
let oracle_data_slot = clock.slot - oracle_data.delay.max(0i64).cast::<u64>()?;
11171118
if constituent.last_oracle_slot < oracle_data_slot {
@@ -1150,6 +1151,12 @@ pub fn handle_deposit_to_program_vault<'c: 'info, 'info>(
11501151
ctx.accounts.spot_market_vault.reload()?;
11511152
spot_market.validate_max_token_deposits_and_borrows(false)?;
11521153

1154+
validate!(
1155+
ctx.accounts.spot_market_vault.amount == deposit_plus_token_amount_before,
1156+
ErrorCode::LpInvariantFailed,
1157+
"Spot market vault amount mismatch after deposit"
1158+
)?;
1159+
11531160
Ok(())
11541161
}
11551162

programs/drift/src/state/events.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,6 @@ pub struct LPSwapRecord {
760760
pub out_oracle_price: i64,
761761
/// precision: PRICE_PRECISION
762762
pub in_oracle_price: i64,
763-
/// out token mint
764-
pub out_mint: Pubkey,
765-
/// in token mint
766-
pub in_mint: Pubkey,
767763
/// LPPool last_aum, QUOTE_PRECISION
768764
pub last_aum: u128,
769765
pub last_aum_slot: u64,
@@ -802,8 +798,6 @@ pub struct LPMintRedeemRecord {
802798
pub oracle_price: i64,
803799
/// token mint
804800
pub mint: Pubkey,
805-
/// lp mint
806-
pub lp_mint: Pubkey,
807801
/// lp amount, lp mint precision
808802
pub lp_amount: u64,
809803
/// lp fee, lp mint precision

programs/drift/src/state/lp_pool.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,6 @@ pub const MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC: u64 = 10000u64;
4141
#[cfg(not(feature = "anchor-test"))]
4242
pub const MAX_AMM_CACHE_STALENESS_FOR_TARGET_CALC: u64 = 0u64;
4343

44-
#[cfg(feature = "anchor-test")]
45-
pub const MAX_CONSTITUENT_ORACLE_SLOT_STALENESS_FOR_AUM: u64 = 10000u64;
46-
#[cfg(not(feature = "anchor-test"))]
47-
pub const MAX_CONSTITUENT_ORACLE_SLOT_STALENESS_FOR_AUM: u64 = 2u64;
48-
4944
#[cfg(test)]
5045
mod tests;
5146

sdk/src/driftClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9982,7 +9982,7 @@ export class DriftClient {
99829982
): Promise<TransactionInstruction> {
99839983
const remainingAccounts = this.getRemainingAccounts({
99849984
userAccounts: [],
9985-
writableSpotMarketIndexes: [inMarketIndex, outMarketIndex],
9985+
readableSpotMarketIndexes: [inMarketIndex, outMarketIndex],
99869986
});
99879987

99889988
return this.program.instruction.lpPoolSwap(

sdk/src/idl/drift.json

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16543,16 +16543,6 @@
1654316543
"type": "i64",
1654416544
"index": false
1654516545
},
16546-
{
16547-
"name": "outMint",
16548-
"type": "publicKey",
16549-
"index": false
16550-
},
16551-
{
16552-
"name": "inMint",
16553-
"type": "publicKey",
16554-
"index": false
16555-
},
1655616546
{
1655716547
"name": "lastAum",
1655816548
"type": "u128",
@@ -16648,11 +16638,6 @@
1664816638
"type": "publicKey",
1664916639
"index": false
1665016640
},
16651-
{
16652-
"name": "lpMint",
16653-
"type": "publicKey",
16654-
"index": false
16655-
},
1665616641
{
1665716642
"name": "lpAmount",
1665816643
"type": "u64",
@@ -18341,6 +18326,11 @@
1834118326
"code": 6328,
1834218327
"name": "ConstituentOracleStale",
1834318328
"msg": "Constituent oracle is stale"
18329+
},
18330+
{
18331+
"code": 6329,
18332+
"name": "LpInvariantFailed",
18333+
"msg": "LP Invariant failed"
1834418334
}
1834518335
],
1834618336
"metadata": {

0 commit comments

Comments
 (0)