Skip to content

Commit 58cb261

Browse files
crispheaney0xbigz
authored andcommitted
program: add_update_perp_pnl_pool (#1810)
* program: add_update_perp_pnl_pool * test * CHANGELOG
1 parent ffc6750 commit 58cb261

File tree

6 files changed

+180
-0
lines changed

6 files changed

+180
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Features
1111

1212
- program: add new settle pnl invariants ([#1812](https://github.com/drift-labs/protocol-v2/pull/1812))
13+
- program: add update_perp_market_pnl_pool ([#1810](https://github.com/drift-labs/protocol-v2/pull/1810))
1314

1415
### Fixes
1516

programs/drift/src/instructions/admin.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,36 @@ pub fn handle_deposit_into_perp_market_fee_pool<'c: 'info, 'info>(
19671967
Ok(())
19681968
}
19691969

1970+
#[access_control(
1971+
perp_market_valid(&ctx.accounts.perp_market)
1972+
)]
1973+
pub fn handle_update_perp_market_pnl_pool<'c: 'info, 'info>(
1974+
ctx: Context<'_, '_, 'c, 'info, UpdatePerpMarketPnlPool<'info>>,
1975+
amount: u64,
1976+
) -> Result<()> {
1977+
let perp_market = &mut load_mut!(ctx.accounts.perp_market)?;
1978+
1979+
let spot_market = &mut load_mut!(ctx.accounts.spot_market)?;
1980+
1981+
controller::spot_balance::update_spot_balances(
1982+
amount.cast::<u128>()?,
1983+
&SpotBalanceType::Deposit,
1984+
spot_market,
1985+
&mut perp_market.pnl_pool,
1986+
false,
1987+
)?;
1988+
1989+
validate_spot_market_vault_amount(spot_market, ctx.accounts.spot_market_vault.amount)?;
1990+
1991+
msg!(
1992+
"updating perp market {} pnl pool with amount {}",
1993+
perp_market.market_index,
1994+
amount
1995+
);
1996+
1997+
Ok(())
1998+
}
1999+
19702000
#[access_control(
19712001
deposit_not_paused(&ctx.accounts.state)
19722002
spot_market_valid(&ctx.accounts.spot_market)
@@ -5261,6 +5291,29 @@ pub struct SettleExpiredMarketPoolsToRevenuePool<'info> {
52615291
pub perp_market: AccountLoader<'info, PerpMarket>,
52625292
}
52635293

5294+
#[derive(Accounts)]
5295+
pub struct UpdatePerpMarketPnlPool<'info> {
5296+
#[account(
5297+
has_one = admin
5298+
)]
5299+
pub state: Box<Account<'info, State>>,
5300+
pub admin: Signer<'info>,
5301+
#[account(
5302+
seeds = [b"spot_market", 0_u16.to_le_bytes().as_ref()],
5303+
bump,
5304+
mut
5305+
)]
5306+
pub spot_market: AccountLoader<'info, SpotMarket>,
5307+
#[account(
5308+
mut,
5309+
seeds = [b"spot_market_vault".as_ref(), 0_u16.to_le_bytes().as_ref()],
5310+
bump,
5311+
)]
5312+
pub spot_market_vault: Box<InterfaceAccount<'info, TokenAccount>>,
5313+
#[account(mut)]
5314+
pub perp_market: AccountLoader<'info, PerpMarket>,
5315+
}
5316+
52645317
#[derive(Accounts)]
52655318
pub struct DepositIntoMarketFeePool<'info> {
52665319
#[account(

programs/drift/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,13 @@ pub mod drift {
10871087
handle_deposit_into_perp_market_fee_pool(ctx, amount)
10881088
}
10891089

1090+
pub fn update_perp_market_pnl_pool<'c: 'info, 'info>(
1091+
ctx: Context<'_, '_, 'c, 'info, UpdatePerpMarketPnlPool<'info>>,
1092+
amount: u64,
1093+
) -> Result<()> {
1094+
handle_update_perp_market_pnl_pool(ctx, amount)
1095+
}
1096+
10901097
pub fn deposit_into_spot_market_vault<'c: 'info, 'info>(
10911098
ctx: Context<'_, '_, 'c, 'info, DepositIntoSpotMarketVault<'info>>,
10921099
amount: u64,

sdk/src/adminClient.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,42 @@ export class AdminClient extends DriftClient {
10791079
});
10801080
}
10811081

1082+
public async updatePerpMarketPnlPool(
1083+
perpMarketIndex: number,
1084+
amount: BN
1085+
): Promise<TransactionSignature> {
1086+
const updatePerpMarketPnlPoolIx = await this.getUpdatePerpMarketPnlPoolIx(
1087+
perpMarketIndex,
1088+
amount
1089+
);
1090+
1091+
const tx = await this.buildTransaction(updatePerpMarketPnlPoolIx);
1092+
1093+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
1094+
1095+
return txSig;
1096+
}
1097+
1098+
public async getUpdatePerpMarketPnlPoolIx(
1099+
perpMarketIndex: number,
1100+
amount: BN
1101+
): Promise<TransactionInstruction> {
1102+
return await this.program.instruction.updatePerpMarketPnlPool(amount, {
1103+
accounts: {
1104+
admin: this.isSubscribed
1105+
? this.getStateAccount().admin
1106+
: this.wallet.publicKey,
1107+
state: await this.getStatePublicKey(),
1108+
perpMarket: await getPerpMarketPublicKey(
1109+
this.program.programId,
1110+
perpMarketIndex
1111+
),
1112+
spotMarket: this.getQuoteSpotMarketAccount().pubkey,
1113+
spotMarketVault: this.getQuoteSpotMarketAccount().vault,
1114+
},
1115+
});
1116+
}
1117+
10821118
public async depositIntoSpotMarketVault(
10831119
spotMarketIndex: number,
10841120
amount: BN,

sdk/src/idl/drift.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4832,6 +4832,42 @@
48324832
}
48334833
]
48344834
},
4835+
{
4836+
"name": "updatePerpMarketPnlPool",
4837+
"accounts": [
4838+
{
4839+
"name": "state",
4840+
"isMut": false,
4841+
"isSigner": false
4842+
},
4843+
{
4844+
"name": "admin",
4845+
"isMut": false,
4846+
"isSigner": true
4847+
},
4848+
{
4849+
"name": "spotMarket",
4850+
"isMut": true,
4851+
"isSigner": false
4852+
},
4853+
{
4854+
"name": "spotMarketVault",
4855+
"isMut": true,
4856+
"isSigner": false
4857+
},
4858+
{
4859+
"name": "perpMarket",
4860+
"isMut": true,
4861+
"isSigner": false
4862+
}
4863+
],
4864+
"args": [
4865+
{
4866+
"name": "amount",
4867+
"type": "u64"
4868+
}
4869+
]
4870+
},
48354871
{
48364872
"name": "depositIntoSpotMarketVault",
48374873
"accounts": [

tests/admin.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import {
66
BN,
77
ExchangeStatus,
88
getPythLazerOraclePublicKey,
9+
getTokenAmount,
910
loadKeypair,
1011
OracleGuardRails,
1112
OracleSource,
13+
SpotBalanceType,
1214
TestClient,
1315
Wallet,
1416
} from '../sdk/src';
@@ -19,13 +21,15 @@ import {
1921
initializeQuoteSpotMarket,
2022
mockOracleNoProgram,
2123
mockUSDCMint,
24+
mockUserUSDCAccount,
2225
} from './testHelpers';
2326
import { PublicKey } from '@solana/web3.js';
2427
import {
2528
BankrunContextWrapper,
2629
Connection,
2730
} from '../sdk/src/bankrun/bankrunConnection';
2831
import { TestBulkAccountLoader } from '../sdk/src/accounts/testBulkAccountLoader';
32+
import { createTransferCheckedInstruction } from '@solana/spl-token';
2933

3034
describe('admin', () => {
3135
const chProgram = anchor.workspace.Drift as Program;
@@ -36,6 +40,10 @@ describe('admin', () => {
3640

3741
let usdcMint;
3842

43+
let userUSDCAccount;
44+
45+
const usdcAmount = new BN(10 * 10 ** 6);
46+
3947
let bankrunContextWrapper: BankrunContextWrapper;
4048

4149
before(async () => {
@@ -72,6 +80,13 @@ describe('admin', () => {
7280
},
7381
});
7482

83+
userUSDCAccount = await mockUserUSDCAccount(
84+
usdcMint,
85+
usdcAmount,
86+
bankrunContextWrapper,
87+
driftClient.wallet.publicKey
88+
);
89+
7590
await driftClient.initialize(usdcMint.publicKey, true);
7691
await driftClient.subscribe();
7792
await driftClient.initializeUserAccount(0);
@@ -457,6 +472,38 @@ describe('admin', () => {
457472
assert(perpMarket.amm.ammSpreadAdjustment == ammSpreadAdjustment);
458473
});
459474

475+
it('update pnl pool', async () => {
476+
const quoteVault = driftClient.getSpotMarketAccount(0).vault;
477+
478+
const splTransferIx = createTransferCheckedInstruction(
479+
userUSDCAccount.publicKey,
480+
usdcMint.publicKey,
481+
quoteVault,
482+
driftClient.wallet.publicKey,
483+
usdcAmount.toNumber(),
484+
6
485+
);
486+
487+
const tx = await driftClient.buildTransaction(splTransferIx);
488+
// @ts-ignore
489+
await driftClient.sendTransaction(tx);
490+
491+
await driftClient.updatePerpMarketPnlPool(0, usdcAmount);
492+
493+
await driftClient.fetchAccounts();
494+
495+
const perpMarket = driftClient.getPerpMarketAccount(0);
496+
const spotMarket = driftClient.getSpotMarketAccount(0);
497+
498+
const tokenAmount = getTokenAmount(
499+
perpMarket.pnlPool.scaledBalance,
500+
spotMarket,
501+
SpotBalanceType.DEPOSIT
502+
);
503+
504+
assert(tokenAmount.eq(usdcAmount));
505+
});
506+
460507
it('Update admin', async () => {
461508
const newAdminKey = PublicKey.default;
462509

0 commit comments

Comments
 (0)