Skip to content

Commit

Permalink
program: add ix to pause deposits/withdraws if vault invariant broken (
Browse files Browse the repository at this point in the history
…#1387)

* program: add ix to pause deposits/withdraws if vault invariant broken

* add test

* update test

* cargo fmt --

* fix prettify:lint

* CHANGELOG
  • Loading branch information
crispheaney authored Jan 2, 2025
1 parent 9ba9b97 commit 5f876cf
Show file tree
Hide file tree
Showing 8 changed files with 396 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- program: add ix to pause deposits/withdraws if vault invariant broken ([#1387](https://github.com/drift-labs/protocol-v2/pull/1387))

### Fixes

- program: skip liq perp oracle twap check if market is in settlement ([#1406](https://github.com/drift-labs/protocol-v2/pull/1406))
Expand Down
35 changes: 34 additions & 1 deletion programs/drift/src/instructions/keeper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use crate::state::high_leverage_mode_config::HighLeverageModeConfig;
use crate::state::insurance_fund_stake::InsuranceFundStake;
use crate::state::oracle_map::OracleMap;
use crate::state::order_params::{OrderParams, PlaceOrderOptions, SwiftOrderParamsMessage};
use crate::state::paused_operations::PerpOperation;
use crate::state::paused_operations::{PerpOperation, SpotOperation};
use crate::state::perp_market::{ContractType, MarketStatus, PerpMarket};
use crate::state::perp_market_map::{
get_market_set_for_spot_positions, get_market_set_for_user_positions, get_market_set_from_list,
Expand Down Expand Up @@ -2414,6 +2414,26 @@ pub fn handle_force_delete_user<'c: 'info, 'info>(
Ok(())
}

pub fn handle_pause_spot_market_deposit_withdraw(
ctx: Context<PauseSpotMarketDepositWithdraw>,
) -> Result<()> {
let spot_market = &mut load_mut!(ctx.accounts.spot_market)?;

let result =
validate_spot_market_vault_amount(spot_market, ctx.accounts.spot_market_vault.amount);

validate!(
matches!(result, Err(ErrorCode::SpotMarketVaultInvariantViolated)),
ErrorCode::DefaultError,
"spot market vault amount is valid"
)?;

spot_market.paused_operations = spot_market.paused_operations | SpotOperation::Deposit as u8;
spot_market.paused_operations = spot_market.paused_operations | SpotOperation::Withdraw as u8;

Ok(())
}

#[derive(Accounts)]
pub struct FillOrder<'info> {
pub state: Box<Account<'info, State>>,
Expand Down Expand Up @@ -2910,3 +2930,16 @@ pub struct ForceDeleteUser<'info> {
/// CHECK: forced drift_signer
pub drift_signer: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct PauseSpotMarketDepositWithdraw<'info> {
pub state: Box<Account<'info, State>>,
pub keeper: Signer<'info>,
#[account(mut)]
pub spot_market: AccountLoader<'info, SpotMarket>,
#[account(
seeds = [b"spot_market_vault".as_ref(), spot_market.load()?.market_index.to_le_bytes().as_ref()],
bump,
)]
pub spot_market_vault: Box<InterfaceAccount<'info, TokenAccount>>,
}
6 changes: 6 additions & 0 deletions programs/drift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,12 @@ pub mod drift {
handle_post_multi_pyth_pull_oracle_updates_atomic(ctx, params)
}

pub fn pause_spot_market_deposit_withdraw(
ctx: Context<PauseSpotMarketDepositWithdraw>,
) -> Result<()> {
handle_pause_spot_market_deposit_withdraw(ctx)
}

// Admin Instructions

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
Expand Down
29 changes: 29 additions & 0 deletions sdk/src/driftClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8937,6 +8937,35 @@ export class DriftClient {
return ix;
}

public async getPauseSpotMarketDepositWithdrawIx(
spotMarketIndex: number
): Promise<TransactionInstruction> {
const spotMarket = await this.getSpotMarketAccount(spotMarketIndex);
return this.program.instruction.pauseSpotMarketDepositWithdraw({
accounts: {
state: await this.getStatePublicKey(),
keeper: this.wallet.publicKey,
spotMarket: spotMarket.pubkey,
spotMarketVault: spotMarket.vault,
},
});
}

public async pauseSpotMarketDepositWithdraw(
spotMarketIndex: number,
txParams?: TxParams
): Promise<TransactionSignature> {
const { txSig } = await this.sendTransaction(
await this.buildTransaction(
await this.getPauseSpotMarketDepositWithdrawIx(spotMarketIndex),
txParams
),
[],
this.opts
);
return txSig;
}

private handleSignedTransaction(signedTxs: SignedTxData[]) {
if (this.enableMetricsEvents && this.metricsEventEmitter) {
this.metricsEventEmitter.emit('txSigned', signedTxs);
Expand Down
26 changes: 26 additions & 0 deletions sdk/src/idl/drift.json
Original file line number Diff line number Diff line change
Expand Up @@ -3280,6 +3280,32 @@
}
]
},
{
"name": "pauseSpotMarketDepositWithdraw",
"accounts": [
{
"name": "state",
"isMut": false,
"isSigner": false
},
{
"name": "keeper",
"isMut": false,
"isSigner": true
},
{
"name": "spotMarket",
"isMut": true,
"isSigner": false
},
{
"name": "spotMarketVault",
"isMut": false,
"isSigner": false
}
],
"args": []
},
{
"name": "initialize",
"accounts": [
Expand Down
1 change: 1 addition & 0 deletions test-scripts/run-anchor-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ test_files=(
order.ts
ordersWithSpread.ts
pauseExchange.ts
pauseDepositWithdraw.ts
perpLpJit.ts
perpLpRiskMitigation.ts
phoenixTest.ts
Expand Down
Loading

0 comments on commit 5f876cf

Please sign in to comment.