zero out perp position and orders for a broken market (#413)

* zero out  perp position and orders for a broken market

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* fix

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* client code

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* fixes from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2023-01-23 12:50:20 +01:00 committed by GitHub
parent c30fa1dbb3
commit f0c797a2e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 0 deletions

View File

@ -29,6 +29,7 @@ pub use perp_place_order::*;
pub use perp_settle_fees::*;
pub use perp_settle_pnl::*;
pub use perp_update_funding::*;
pub use perp_zero_out::*;
pub use serum3_cancel_all_orders::*;
pub use serum3_cancel_order::*;
pub use serum3_close_open_orders::*;
@ -84,6 +85,7 @@ mod perp_place_order;
mod perp_settle_fees;
mod perp_settle_pnl;
mod perp_update_funding;
mod perp_zero_out;
mod serum3_cancel_all_orders;
mod serum3_cancel_order;
mod serum3_close_open_orders;

View File

@ -0,0 +1,48 @@
use anchor_lang::prelude::*;
use crate::error::*;
use crate::state::*;
#[derive(Accounts)]
pub struct PerpZeroOutForMarket<'info> {
#[account(
has_one = admin,
constraint = group.load()?.is_operational() @ MangoError::GroupIsHalted,
constraint = group.load()?.is_testing()
)]
pub group: AccountLoader<'info, Group>,
#[account(
mut,
has_one = group,
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
)]
pub account: AccountLoader<'info, MangoAccountFixed>,
#[account(
has_one = group,
constraint = perp_market.load()?.perp_market_index == 1
)]
pub perp_market: AccountLoader<'info, PerpMarket>,
pub admin: Signer<'info>,
}
pub fn perp_zero_out_for_market(ctx: Context<PerpZeroOutForMarket>) -> Result<()> {
let mut account = ctx.accounts.account.load_full_mut()?;
let perp_market = ctx.accounts.perp_market.load()?;
let perp_position = account.perp_position_mut(perp_market.perp_market_index)?;
*perp_position = PerpPosition::default();
for i in 0..account.header.perp_oo_count() {
let oo = account.perp_order_mut_by_raw_index(i);
if !oo.is_active_for_market(perp_market.perp_market_index) {
continue;
}
*oo = PerpOpenOrder::default();
}
Ok(())
}

View File

@ -557,6 +557,10 @@ pub mod mango_v4 {
instructions::perp_deactivate_position(ctx)
}
pub fn perp_zero_out_for_market(ctx: Context<PerpZeroOutForMarket>) -> Result<()> {
instructions::perp_zero_out_for_market(ctx)
}
#[allow(clippy::too_many_arguments)]
pub fn perp_place_order(
ctx: Context<PerpPlaceOrder>,

View File

@ -1900,6 +1900,23 @@ export class MangoClient {
);
}
public async perpZeroOutForMarket(
group: Group,
mangoAccount: MangoAccount,
perpMarketIndex: PerpMarketIndex,
): Promise<TransactionSignature> {
const perpMarket = group.getPerpMarketByMarketIndex(perpMarketIndex);
return await this.program.methods
.perpZeroOutForMarket()
.accounts({
group: group.publicKey,
account: mangoAccount.publicKey,
perpMarket: perpMarket.publicKey,
admin: group.admin,
})
.rpc();
}
public async perpPlaceOrder(
group: Group,
mangoAccount: MangoAccount,

View File

@ -2858,6 +2858,32 @@ export type MangoV4 = {
],
"args": []
},
{
"name": "perpZeroOutForMarket",
"accounts": [
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "perpMarket",
"isMut": false,
"isSigner": false
},
{
"name": "admin",
"isMut": false,
"isSigner": true
}
],
"args": []
},
{
"name": "perpPlaceOrder",
"accounts": [
@ -10748,6 +10774,32 @@ export const IDL: MangoV4 = {
],
"args": []
},
{
"name": "perpZeroOutForMarket",
"accounts": [
{
"name": "group",
"isMut": false,
"isSigner": false
},
{
"name": "account",
"isMut": true,
"isSigner": false
},
{
"name": "perpMarket",
"isMut": false,
"isSigner": false
},
{
"name": "admin",
"isMut": false,
"isSigner": true
}
],
"args": []
},
{
"name": "perpPlaceOrder",
"accounts": [