Skip to content

Commit 34e9f99

Browse files
authored
added more settle test coverage and squash bugs (#1689)
1 parent 0871d9d commit 34e9f99

File tree

3 files changed

+98
-4
lines changed

3 files changed

+98
-4
lines changed

programs/drift/src/instructions/keeper.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3114,10 +3114,11 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31143114
)?;
31153115

31163116
// Send all revenues to the perp market fee pool
3117+
let precision_increase = SPOT_BALANCE_PRECISION.safe_div(QUOTE_PRECISION)?;
31173118
perp_market
31183119
.amm
31193120
.fee_pool
3120-
.increase_balance(amount_to_send as u128)?;
3121+
.increase_balance((amount_to_send as u128).safe_mul(precision_increase)?)?;
31213122

31223123
lp_pool.cumulative_usdc_sent_to_perp_markets = lp_pool
31233124
.cumulative_usdc_sent_to_perp_markets
@@ -3131,10 +3132,14 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31313132
} else {
31323133
let amount_to_send = if cached_info.quote_owed_from_lp > 0 {
31333134
if amount_to_send > cached_info.quote_owed_from_lp as u64 {
3135+
let new_amount_to_send =
3136+
amount_to_send.safe_sub(cached_info.quote_owed_from_lp as u64)?;
31343137
cached_info.quote_owed_from_lp = 0;
3135-
amount_to_send - cached_info.quote_owed_from_lp as u64
3138+
new_amount_to_send
31363139
} else {
3137-
cached_info.quote_owed_from_lp -= amount_to_send as i64;
3140+
cached_info.quote_owed_from_lp = cached_info
3141+
.quote_owed_from_lp
3142+
.safe_sub(amount_to_send as i64)?;
31383143
0
31393144
}
31403145
} else {
@@ -3196,6 +3201,9 @@ pub fn handle_settle_perp_to_lp_pool<'c: 'info, 'info>(
31963201
lp_pool.last_aum = lp_pool
31973202
.last_aum
31983203
.saturating_add(amount_to_send.cast::<u128>()?);
3204+
} else {
3205+
cached_info.last_fee_pool_token_amount = fee_pool_token_amount;
3206+
cached_info.last_net_pnl_pool_token_amount = net_pnl_pool_token_amount;
31993207
}
32003208
}
32013209

sdk/src/adminClient.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,13 @@ export class AdminClient extends DriftClient {
11151115
sourceVault: PublicKey
11161116
): Promise<TransactionInstruction> {
11171117
const spotMarket = this.getQuoteSpotMarketAccount();
1118+
const remainingAccounts = [
1119+
{
1120+
pubkey: spotMarket.mint,
1121+
isWritable: false,
1122+
isSigner: false,
1123+
},
1124+
];
11181125

11191126
return await this.program.instruction.depositIntoPerpMarketFeePool(amount, {
11201127
accounts: {
@@ -1132,6 +1139,7 @@ export class AdminClient extends DriftClient {
11321139
spotMarketVault: spotMarket.vault,
11331140
tokenProgram: TOKEN_PROGRAM_ID,
11341141
},
1142+
remainingAccounts,
11351143
});
11361144
}
11371145

tests/lpPool.ts

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
SPOT_MARKET_BALANCE_PRECISION,
4444
SpotBalanceType,
4545
getTokenAmount,
46+
TWO,
4647
} from '../sdk/src';
4748

4849
import {
@@ -780,7 +781,7 @@ describe('LP Pool', () => {
780781
);
781782
});
782783

783-
it('will fail gracefully when trying to settle pnl from constituents to perp markets if not enough usdc in the constituent vault', async () => {
784+
it('will settle gracefully when trying to settle pnl from constituents to perp markets if not enough usdc in the constituent vault', async () => {
784785
let lpPool = (await adminClient.program.account.lpPool.fetch(
785786
lpPoolKey
786787
)) as LPPoolAccount;
@@ -876,8 +877,85 @@ describe('LP Pool', () => {
876877
)
877878
)
878879
);
880+
assert(
881+
adminClient
882+
.getPerpMarketAccount(0)
883+
.amm.feePool.scaledBalance.eq(
884+
new BN(constituentUSDCBalanceBefore.toString()).mul(
885+
SPOT_MARKET_BALANCE_PRECISION.div(QUOTE_PRECISION)
886+
)
887+
)
888+
);
879889

880890
// NAV should have gone down the max that is has
881891
assert(lpPool.lastAum.eq(ZERO));
882892
});
893+
894+
it('perp market will not transfer with the constituent vault if it is owed from dlp', async () => {
895+
let ammCache = (await adminClient.program.account.ammCache.fetch(
896+
getAmmCachePublicKey(program.programId)
897+
)) as AmmCache;
898+
const owedAmount = ammCache.cache[0].quoteOwedFromLp;
899+
900+
// Give the perp market half of its owed amount
901+
const perpMarket = adminClient.getPerpMarketAccount(0);
902+
perpMarket.amm.feePool.scaledBalance =
903+
perpMarket.amm.feePool.scaledBalance.add(
904+
owedAmount
905+
.div(TWO)
906+
.mul(SPOT_MARKET_BALANCE_PRECISION.div(QUOTE_PRECISION))
907+
);
908+
await overWritePerpMarket(
909+
adminClient,
910+
bankrunContextWrapper,
911+
perpMarket.pubkey,
912+
perpMarket
913+
);
914+
915+
await adminClient.settlePerpToLpPool(encodeName(lpPoolName), [0, 1, 2]);
916+
917+
ammCache = (await adminClient.program.account.ammCache.fetch(
918+
getAmmCachePublicKey(program.programId)
919+
)) as AmmCache;
920+
const constituent = (await adminClient.program.account.constituent.fetch(
921+
getConstituentPublicKey(program.programId, lpPoolKey, 0)
922+
)) as ConstituentAccount;
923+
924+
assert(ammCache.cache[0].quoteOwedFromLp.eq(owedAmount.divn(2)));
925+
assert(constituent.tokenBalance.eq(ZERO));
926+
});
927+
928+
it('perp market will transfer with the constituent vault if it should send more than its owed', async () => {
929+
let ammCache = (await adminClient.program.account.ammCache.fetch(
930+
getAmmCachePublicKey(program.programId)
931+
)) as AmmCache;
932+
const owedAmount = ammCache.cache[0].quoteOwedFromLp;
933+
934+
// Give the perp market half of its owed amount
935+
const perpMarket = adminClient.getPerpMarketAccount(0);
936+
perpMarket.amm.feePool.scaledBalance =
937+
perpMarket.amm.feePool.scaledBalance.add(
938+
owedAmount
939+
.mul(TWO)
940+
.mul(SPOT_MARKET_BALANCE_PRECISION.div(QUOTE_PRECISION))
941+
);
942+
await overWritePerpMarket(
943+
adminClient,
944+
bankrunContextWrapper,
945+
perpMarket.pubkey,
946+
perpMarket
947+
);
948+
949+
await adminClient.settlePerpToLpPool(encodeName(lpPoolName), [0, 1, 2]);
950+
951+
ammCache = (await adminClient.program.account.ammCache.fetch(
952+
getAmmCachePublicKey(program.programId)
953+
)) as AmmCache;
954+
const constituent = (await adminClient.program.account.constituent.fetch(
955+
getConstituentPublicKey(program.programId, lpPoolKey, 0)
956+
)) as ConstituentAccount;
957+
958+
assert(ammCache.cache[0].quoteOwedFromLp.eq(ZERO));
959+
assert(constituent.tokenBalance.eq(owedAmount));
960+
});
883961
});

0 commit comments

Comments
 (0)