Skip to content

Commit 3bf665d

Browse files
authored
Nour/settle pnl fix (#1817)
* settle perp to lp pool bug fixes * update bankrun test to not use admin fee pool deposit * fix tests using update spot market balances too
1 parent dca7093 commit 3bf665d

File tree

6 files changed

+67
-36
lines changed

6 files changed

+67
-36
lines changed

programs/drift/src/instructions/admin.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,12 @@ pub fn handle_deposit_into_perp_market_fee_pool<'c: 'info, 'info>(
20742074

20752075
let quote_spot_market = &mut load_mut!(ctx.accounts.quote_spot_market)?;
20762076

2077+
controller::spot_balance::update_spot_market_cumulative_interest(
2078+
&mut *quote_spot_market,
2079+
None,
2080+
Clock::get()?.unix_timestamp,
2081+
)?;
2082+
20772083
controller::spot_balance::update_spot_balances(
20782084
amount.cast::<u128>()?,
20792085
&SpotBalanceType::Deposit,

programs/drift/src/instructions/keeper.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3137,6 +3137,7 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31373137

31383138
let slot = Clock::get()?.slot;
31393139
let state = &ctx.accounts.state;
3140+
let now = Clock::get()?.unix_timestamp;
31403141

31413142
if !state.allow_settle_lp_pool() {
31423143
msg!("settle lp pool disabled");
@@ -3147,7 +3148,7 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31473148
let amm_cache_key = &ctx.accounts.amm_cache.key();
31483149
let mut amm_cache: AccountZeroCopyMut<'_, CacheInfo, _> =
31493150
ctx.accounts.amm_cache.load_zc_mut()?;
3150-
let quote_market = &ctx.accounts.quote_market.load_mut()?;
3151+
let quote_market = &mut ctx.accounts.quote_market.load_mut()?;
31513152
let mut quote_constituent = ctx.accounts.constituent.load_mut()?;
31523153
let constituent_token_account = &mut ctx.accounts.constituent_quote_token_account;
31533154
let mut lp_pool = ctx.accounts.lp_pool.load_mut()?;
@@ -3180,9 +3181,14 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31803181
None,
31813182
)?;
31823183

3183-
let precision_increase = SPOT_BALANCE_PRECISION.safe_div(QUOTE_PRECISION)?;
31843184
let mint = Some(*ctx.accounts.mint.clone());
31853185

3186+
controller::spot_balance::update_spot_market_cumulative_interest(
3187+
&mut *quote_market,
3188+
None,
3189+
now,
3190+
)?;
3191+
31863192
for (_, perp_market_loader) in perp_market_map.0.iter() {
31873193
let mut perp_market = perp_market_loader.load_mut()?;
31883194
if perp_market.lp_status == 0 {
@@ -3277,7 +3283,11 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
32773283
}
32783284

32793285
// Update market pools
3280-
update_perp_market_pools(&mut perp_market, &settlement_result, precision_increase)?;
3286+
update_perp_market_pools_and_quote_market_balance(
3287+
&mut perp_market,
3288+
&settlement_result,
3289+
quote_market,
3290+
)?;
32813291

32823292
// Calculate new quote owed amount
32833293
let new_quote_owed = match settlement_result.direction {
@@ -3314,6 +3324,7 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
33143324
}
33153325

33163326
// Final validation
3327+
ctx.accounts.quote_token_vault.reload()?;
33173328
math::spot_withdraw::validate_spot_market_vault_amount(
33183329
quote_market,
33193330
ctx.accounts.quote_token_vault.amount,

programs/drift/src/math/lp_pool.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod perp_lp_pool_settlement {
22
use core::slice::Iter;
33
use std::iter::Peekable;
44

5+
use crate::state::spot_market::SpotBalanceType;
56
use crate::{
67
math::safe_math::SafeMath,
78
state::{
@@ -124,28 +125,39 @@ pub mod perp_lp_pool_settlement {
124125
}
125126

126127
// Market state updates
127-
pub fn update_perp_market_pools(
128+
pub fn update_perp_market_pools_and_quote_market_balance(
128129
perp_market: &mut PerpMarket,
129130
result: &SettlementResult,
130-
precision_increase: u128,
131+
quote_spot_market: &mut SpotMarket,
131132
) -> Result<()> {
132133
match result.direction {
133134
SettlementDirection::FromLpPool => {
134-
perp_market.amm.fee_pool.increase_balance(
135-
(result.amount_transferred as u128).safe_mul(precision_increase)?,
135+
controller::spot_balance::update_spot_balances(
136+
(result.amount_transferred as u128),
137+
&SpotBalanceType::Deposit,
138+
quote_spot_market,
139+
&mut perp_market.amm.fee_pool,
140+
false,
136141
)?;
137142
}
138143
SettlementDirection::ToLpPool => {
139144
if result.fee_pool_used > 0 {
140-
perp_market
141-
.amm
142-
.fee_pool
143-
.decrease_balance(result.fee_pool_used.safe_mul(precision_increase)?)?;
145+
controller::spot_balance::update_spot_balances(
146+
result.fee_pool_used,
147+
&SpotBalanceType::Borrow,
148+
quote_spot_market,
149+
&mut perp_market.amm.fee_pool,
150+
true,
151+
)?;
144152
}
145153
if result.pnl_pool_used > 0 {
146-
perp_market
147-
.pnl_pool
148-
.decrease_balance(result.pnl_pool_used.safe_mul(precision_increase)?)?;
154+
controller::spot_balance::update_spot_balances(
155+
result.pnl_pool_used,
156+
&SpotBalanceType::Borrow,
157+
quote_spot_market,
158+
&mut perp_market.pnl_pool,
159+
true,
160+
)?;
149161
}
150162
}
151163
SettlementDirection::None => {}

sdk/src/adminClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5870,7 +5870,7 @@ export class AdminClient extends DriftClient {
58705870
const depositIx = await this.getDepositToProgramVaultIx(
58715871
lpPoolName,
58725872
depositMarketIndex,
5873-
amountToDeposit,
5873+
amountToDeposit
58745874
);
58755875

58765876
const tx = await this.buildTransaction([depositIx]);

sdk/src/constituentMap/constituentMap.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ export interface ConstituentMapInterface {
4040
has(key: string): boolean;
4141
get(key: string): ConstituentAccount | undefined;
4242
getFromSpotMarketIndex(
43-
spotMarketIndex: number): ConstituentAccount | undefined;
43+
spotMarketIndex: number
44+
): ConstituentAccount | undefined;
4445
getFromConstituentIndex(
45-
constituentIndex: number): ConstituentAccount | undefined;
46-
46+
constituentIndex: number
47+
): ConstituentAccount | undefined;
48+
4749
getWithSlot(key: string): DataAndSlot<ConstituentAccount> | undefined;
4850
mustGet(key: string): Promise<ConstituentAccount>;
4951
mustGetWithSlot(key: string): Promise<DataAndSlot<ConstituentAccount>>;
@@ -180,12 +182,16 @@ export class ConstituentMap implements ConstituentMapInterface {
180182
return this.constituentMap.get(key)?.data;
181183
}
182184

183-
public getFromConstituentIndex(constituentIndex: number): ConstituentAccount | undefined {
185+
public getFromConstituentIndex(
186+
constituentIndex: number
187+
): ConstituentAccount | undefined {
184188
const key = this.constituentIndexToKeyMap.get(constituentIndex);
185189
return key ? this.get(key) : undefined;
186190
}
187191

188-
public getFromSpotMarketIndex(spotMarketIndex: number): ConstituentAccount | undefined {
192+
public getFromSpotMarketIndex(
193+
spotMarketIndex: number
194+
): ConstituentAccount | undefined {
189195
const key = this.spotMarketIndexToKeyMap.get(spotMarketIndex);
190196
return key ? this.get(key) : undefined;
191197
}
@@ -263,13 +269,7 @@ export class ConstituentMap implements ConstituentMapInterface {
263269
slot,
264270
});
265271
}
266-
this.constituentIndexToKeyMap.set(
267-
constituentAccount.constituentIndex,
268-
key
269-
);
270-
this.spotMarketIndexToKeyMap.set(
271-
constituentAccount.spotMarketIndex,
272-
key
273-
);
272+
this.constituentIndexToKeyMap.set(constituentAccount.constituentIndex, key);
273+
this.spotMarketIndexToKeyMap.set(constituentAccount.spotMarketIndex, key);
274274
}
275275
}

tests/lpPool.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,9 @@ describe('LP Pool', () => {
984984
console.log('feePoolBalanceBefore', feePoolBalance0.toString());
985985
console.log('feePoolBalanceAfter', feePoolBalanceAfter.toString());
986986
// Fee pool can cover it all in first perp market
987-
assert(feePoolBalance0.sub(feePoolBalanceAfter).eq(expectedTransfer0));
987+
expect(
988+
feePoolBalance0.sub(feePoolBalanceAfter).toNumber()
989+
).to.be.approximately(expectedTransfer0.toNumber(), 1);
988990

989991
// Constituent sync worked successfully
990992
constituent = (await adminClient.program.account.constituent.fetch(
@@ -1110,12 +1112,13 @@ describe('LP Pool', () => {
11101112
new BN(constituentUSDCBalanceBefore.toString())
11111113
)
11121114
);
1113-
assert(
1114-
ammCache.cache[0].quoteOwedFromLpPool.eq(
1115-
expectedTransferAmount.sub(
1116-
new BN(constituentUSDCBalanceBefore.toString())
1117-
)
1118-
)
1115+
expect(
1116+
ammCache.cache[0].quoteOwedFromLpPool.toNumber()
1117+
).to.be.approximately(
1118+
expectedTransferAmount
1119+
.sub(new BN(constituentUSDCBalanceBefore.toString()))
1120+
.toNumber(),
1121+
1
11191122
);
11201123
assert(
11211124
adminClient
@@ -1471,7 +1474,6 @@ describe('LP Pool', () => {
14711474
await adminClient.settlePerpToLpPool(encodeName(lpPoolName), [0, 1, 2]);
14721475
assert(false, 'Should have thrown');
14731476
} catch (e) {
1474-
console.log(e);
14751477
assert(e.message.includes('0x18bd'));
14761478
}
14771479

0 commit comments

Comments
 (0)