diff --git a/programs/mango-v4/src/error.rs b/programs/mango-v4/src/error.rs index 59af64ddd..732bc0422 100644 --- a/programs/mango-v4/src/error.rs +++ b/programs/mango-v4/src/error.rs @@ -16,4 +16,6 @@ pub enum MangoError { InvalidMarginTradeTargetCpiProgram, #[msg("")] HealthMustBePositive, + #[msg("The account is bankrupt")] + IsBankrupt, } diff --git a/programs/mango-v4/src/instructions/deposit.rs b/programs/mango-v4/src/instructions/deposit.rs index f8b65046b..0f8ab05ad 100644 --- a/programs/mango-v4/src/instructions/deposit.rs +++ b/programs/mango-v4/src/instructions/deposit.rs @@ -4,6 +4,7 @@ use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use fixed::types::I80F48; +use crate::error::*; use crate::state::*; #[derive(Accounts)] @@ -55,6 +56,8 @@ pub fn deposit(ctx: Context, amount: u64) -> Result<()> { // Get the account's position for that token index let mut account = ctx.accounts.account.load_mut()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); + let (position, position_index) = account.token_account_map.get_mut_or_create(token_index)?; // Update the bank and position diff --git a/programs/mango-v4/src/instructions/liq_token_with_token.rs b/programs/mango-v4/src/instructions/liq_token_with_token.rs index 254f3928d..d904b6cf8 100644 --- a/programs/mango-v4/src/instructions/liq_token_with_token.rs +++ b/programs/mango-v4/src/instructions/liq_token_with_token.rs @@ -38,7 +38,10 @@ pub fn liq_token_with_token( let account_retriever = ScanningAccountRetriever::new(ctx.remaining_accounts, group_pk)?; let mut liqor = ctx.accounts.liqor.load_mut()?; + require!(!liqor.is_bankrupt, MangoError::IsBankrupt); + let mut liqee = ctx.accounts.liqee.load_mut()?; + require!(!liqee.is_bankrupt, MangoError::IsBankrupt); // Initial liqee health check let mut liqee_health_cache = health_cache_for_liqee(&liqee, &account_retriever)?; diff --git a/programs/mango-v4/src/instructions/margin_trade.rs b/programs/mango-v4/src/instructions/margin_trade.rs index 2787f9833..a0f04987e 100644 --- a/programs/mango-v4/src/instructions/margin_trade.rs +++ b/programs/mango-v4/src/instructions/margin_trade.rs @@ -27,6 +27,7 @@ pub fn margin_trade<'key, 'accounts, 'remaining, 'info>( ) -> Result<()> { let group = ctx.accounts.group.load()?; let mut account = ctx.accounts.account.load_mut()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); // remaining_accounts layout is expected as follows // * banks_len number of banks diff --git a/programs/mango-v4/src/instructions/place_perp_order.rs b/programs/mango-v4/src/instructions/place_perp_order.rs index 185218fca..5327dca2e 100644 --- a/programs/mango-v4/src/instructions/place_perp_order.rs +++ b/programs/mango-v4/src/instructions/place_perp_order.rs @@ -1,5 +1,6 @@ use anchor_lang::prelude::*; +use crate::error::*; use crate::state::{ oracle_price, Book, EventQueueHeader, Group, MangoAccount, OrderType, PerpMarket, Queue, Side, }; @@ -49,6 +50,7 @@ pub fn place_perp_order( limit: u8, ) -> Result<()> { let mut mango_account = ctx.accounts.account.load_mut()?; + require!(!mango_account.is_bankrupt, MangoError::IsBankrupt); let mango_account_pk = ctx.accounts.account.key(); let mut perp_market = ctx.accounts.perp_market.load_mut()?; diff --git a/programs/mango-v4/src/instructions/serum3_cancel_order.rs b/programs/mango-v4/src/instructions/serum3_cancel_order.rs index 12241489a..4a3967b18 100644 --- a/programs/mango-v4/src/instructions/serum3_cancel_order.rs +++ b/programs/mango-v4/src/instructions/serum3_cancel_order.rs @@ -95,6 +95,8 @@ pub fn serum3_cancel_order( // { let account = ctx.accounts.account.load()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); + let serum_market = ctx.accounts.serum_market.load()?; // Validate open_orders diff --git a/programs/mango-v4/src/instructions/serum3_create_open_orders.rs b/programs/mango-v4/src/instructions/serum3_create_open_orders.rs index 83547fdff..7ed19c761 100644 --- a/programs/mango-v4/src/instructions/serum3_create_open_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_create_open_orders.rs @@ -1,5 +1,6 @@ use anchor_lang::prelude::*; +use crate::error::*; use crate::state::*; #[derive(Accounts)] @@ -51,6 +52,7 @@ pub fn serum3_create_open_orders(ctx: Context) -> Result let serum_market = ctx.accounts.serum_market.load()?; let mut account = ctx.accounts.account.load_mut()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); let serum_account = account .serum3_account_map .create(serum_market.market_index)?; diff --git a/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs b/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs index a58dfc2d6..87575601d 100644 --- a/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs @@ -65,6 +65,7 @@ pub fn serum3_liq_force_cancel_orders( // { let account = ctx.accounts.account.load()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); let serum_market = ctx.accounts.serum_market.load()?; // Validate open_orders diff --git a/programs/mango-v4/src/instructions/serum3_place_order.rs b/programs/mango-v4/src/instructions/serum3_place_order.rs index 5accc9cb4..b7ea60bfd 100644 --- a/programs/mango-v4/src/instructions/serum3_place_order.rs +++ b/programs/mango-v4/src/instructions/serum3_place_order.rs @@ -157,6 +157,7 @@ pub fn serum3_place_order( // { let account = ctx.accounts.account.load()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); let serum_market = ctx.accounts.serum_market.load()?; // Validate open_orders @@ -241,7 +242,7 @@ pub fn serum3_place_order( let health = compute_health_from_fixed_accounts(&account, HealthType::Init, &ctx.remaining_accounts)?; msg!("health: {}", health); - require!(health >= 0, MangoError::SomeError); + require!(health >= 0, MangoError::HealthMustBePositive); Ok(()) } diff --git a/programs/mango-v4/src/instructions/serum3_settle_funds.rs b/programs/mango-v4/src/instructions/serum3_settle_funds.rs index f19d6c5b0..a297cf623 100644 --- a/programs/mango-v4/src/instructions/serum3_settle_funds.rs +++ b/programs/mango-v4/src/instructions/serum3_settle_funds.rs @@ -64,6 +64,7 @@ pub fn serum3_settle_funds(ctx: Context) -> Result<()> { // { let account = ctx.accounts.account.load()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); let serum_market = ctx.accounts.serum_market.load()?; // Validate open_orders diff --git a/programs/mango-v4/src/instructions/withdraw.rs b/programs/mango-v4/src/instructions/withdraw.rs index e329f6a28..4c80312b2 100644 --- a/programs/mango-v4/src/instructions/withdraw.rs +++ b/programs/mango-v4/src/instructions/withdraw.rs @@ -58,6 +58,8 @@ pub fn withdraw(ctx: Context, amount: u64, allow_borrow: bool) -> Resu // Get the account's position for that token index let mut account = ctx.accounts.account.load_mut()?; + require!(!account.is_bankrupt, MangoError::IsBankrupt); + let (position, position_index) = account.token_account_map.get_mut_or_create(token_index)?; // The bank will also be passed in remainingAccounts. Use an explicit scope @@ -103,7 +105,7 @@ pub fn withdraw(ctx: Context, amount: u64, allow_borrow: bool) -> Resu let health = compute_health_from_fixed_accounts(&account, HealthType::Init, &ctx.remaining_accounts)?; msg!("health: {}", health); - require!(health >= 0, MangoError::SomeError); + require!(health >= 0, MangoError::HealthMustBePositive); // // Deactivate the position only after the health check because the user passed in