Add PerpLiqForceCancelOrders instruction

This commit is contained in:
Christian Kamm 2022-09-08 12:19:03 +02:00
parent 845a32a7c2
commit 810998a2af
3 changed files with 94 additions and 0 deletions

View File

@ -21,6 +21,7 @@ pub use perp_create_market::*;
pub use perp_deactivate_position::*;
pub use perp_edit_market::*;
pub use perp_liq_base_position::*;
pub use perp_liq_force_cancel_orders::*;
pub use perp_place_order::*;
pub use perp_settle_fees::*;
pub use perp_settle_pnl::*;
@ -69,6 +70,7 @@ mod perp_create_market;
mod perp_deactivate_position;
mod perp_edit_market;
mod perp_liq_base_position;
mod perp_liq_force_cancel_orders;
mod perp_place_order;
mod perp_settle_fees;
mod perp_settle_pnl;

View File

@ -0,0 +1,88 @@
use anchor_lang::prelude::*;
use fixed::types::I80F48;
use crate::error::*;
use crate::state::*;
#[derive(Accounts)]
pub struct PerpLiqForceCancelOrders<'info> {
pub group: AccountLoader<'info, Group>,
#[account(mut, has_one = group)]
pub account: AccountLoaderDynamic<'info, MangoAccount>,
#[account(
mut,
has_one = group,
has_one = bids,
has_one = asks
)]
pub perp_market: AccountLoader<'info, PerpMarket>,
#[account(mut)]
pub asks: AccountLoader<'info, BookSide>,
#[account(mut)]
pub bids: AccountLoader<'info, BookSide>,
}
pub fn perp_liq_force_cancel_orders(
ctx: Context<PerpLiqForceCancelOrders>,
limit: u8,
) -> Result<()> {
let mut account = ctx.accounts.account.load_mut()?;
//
// Check liqee health if liquidation is allowed
//
let mut health_cache = {
let mut account = ctx.accounts.account.load_mut()?;
let retriever =
new_fixed_order_account_retriever(ctx.remaining_accounts, &account.borrow())?;
let health_cache =
new_health_cache(&account.borrow(), &retriever).context("create health cache")?;
if account.being_liquidated() {
let init_health = health_cache.health(HealthType::Init);
if account
.fixed
.maybe_recover_from_being_liquidated(init_health)
{
msg!("Liqee init_health above zero");
return Ok(());
}
} else {
let maint_health = health_cache.health(HealthType::Maint);
require!(
maint_health < I80F48::ZERO,
MangoError::HealthMustBeNegative
);
account.fixed.set_being_liquidated(true);
}
health_cache
};
//
// Cancel orders
//
{
let mut perp_market = ctx.accounts.perp_market.load_mut()?;
let bids = ctx.accounts.bids.load_mut()?;
let asks = ctx.accounts.asks.load_mut()?;
let mut book = Book::new(bids, asks);
book.cancel_all_orders(&mut account.borrow_mut(), &mut perp_market, limit, None)?;
let perp_position = account.perp_position(perp_market.perp_market_index)?;
health_cache.recompute_perp_info(perp_position, &perp_market)?;
}
//
// Health check at the end
//
let init_health = health_cache.health(HealthType::Init);
account
.fixed
.maybe_recover_from_being_liquidated(init_health);
Ok(())
}

View File

@ -514,6 +514,10 @@ pub mod mango_v4 {
instructions::perp_liq_base_position(ctx, max_base_transfer)
}
pub fn perp_liq_force_cancel_orders(ctx: Context<PerpLiqForceCancelOrders>) -> Result<()> {
instructions::perp_liq_force_cancel_orders(ctx)
}
// TODO
// perp_force_cancel_order