mango account freeze (#372)
* mango account freeze Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * format Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review 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:
parent
5ef04d6d08
commit
7c69197505
|
@ -81,6 +81,8 @@ pub enum MangoError {
|
|||
HasLiquidatablePerpBasePosition,
|
||||
#[msg("has liquidatable trusted perp pnl")]
|
||||
HasLiquidatableTrustedPerpPnl,
|
||||
#[msg("account is frozen")]
|
||||
AccountIsFrozen,
|
||||
}
|
||||
|
||||
impl MangoError {
|
||||
|
|
|
@ -15,6 +15,7 @@ pub struct AccountClose<'info> {
|
|||
mut,
|
||||
has_one = group,
|
||||
has_one = owner,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen,
|
||||
close = sol_destination
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -14,7 +14,8 @@ pub struct AccountEdit<'info> {
|
|||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
has_one = owner
|
||||
has_one = owner,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
|
|
@ -14,7 +14,8 @@ pub struct AccountExpand<'info> {
|
|||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
has_one = owner
|
||||
has_one = owner,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
use anchor_lang::prelude::*;
|
||||
|
||||
use crate::error::MangoError;
|
||||
use crate::state::*;
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct AccountToggleFreeze<'info> {
|
||||
#[account(
|
||||
constraint = group.load()?.is_operational() @ MangoError::GroupIsHalted,
|
||||
constraint = group.load()?.admin == admin.key() || group.load()?.security_admin == admin.key(),
|
||||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
pub admin: Signer<'info>,
|
||||
}
|
||||
|
||||
// Freezing an account, prevents all instructions involving account (also settling and liquidation), except
|
||||
// perp consume events and force cancellation of orders
|
||||
pub fn account_toggle_freeze(ctx: Context<AccountToggleFreeze>, freeze: bool) -> Result<()> {
|
||||
let mut account = ctx.accounts.account.load_full_mut()?;
|
||||
if freeze {
|
||||
let now_ts: u64 = Clock::get()?.unix_timestamp.try_into().unwrap();
|
||||
account.fixed.frozen_until = now_ts + 7 * 24 * 60 * 60;
|
||||
} else {
|
||||
account.fixed.frozen_until = 0;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -31,6 +31,9 @@ pub mod jupiter_mainnet_3 {
|
|||
/// 4. the mango group
|
||||
#[derive(Accounts)]
|
||||
pub struct FlashLoanBegin<'info> {
|
||||
#[account(
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
// owner is checked at #1
|
||||
pub owner: Signer<'info>,
|
||||
|
@ -53,7 +56,10 @@ pub struct FlashLoanBegin<'info> {
|
|||
/// 4. the mango group
|
||||
#[derive(Accounts)]
|
||||
pub struct FlashLoanEnd<'info> {
|
||||
#[account(mut)]
|
||||
#[account(
|
||||
mut,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
// owner is checked at #1
|
||||
pub owner: Signer<'info>,
|
||||
|
|
|
@ -18,7 +18,10 @@ pub struct HealthRegionBegin<'info> {
|
|||
#[account(address = tx_instructions::ID)]
|
||||
pub instructions: UncheckedAccount<'info>,
|
||||
|
||||
#[account(mut)]
|
||||
#[account(
|
||||
mut,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
}
|
||||
|
||||
|
@ -27,7 +30,10 @@ pub struct HealthRegionBegin<'info> {
|
|||
/// remaining_accounts: health accounts for account
|
||||
#[derive(Accounts)]
|
||||
pub struct HealthRegionEnd<'info> {
|
||||
#[account(mut)]
|
||||
#[account(
|
||||
mut,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ pub use account_close::*;
|
|||
pub use account_create::*;
|
||||
pub use account_edit::*;
|
||||
pub use account_expand::*;
|
||||
pub use account_toggle_freeze::*;
|
||||
pub use alt_extend::*;
|
||||
pub use alt_set::*;
|
||||
pub use benchmark::*;
|
||||
|
@ -56,6 +57,7 @@ mod account_close;
|
|||
mod account_create;
|
||||
mod account_edit;
|
||||
mod account_expand;
|
||||
mod account_toggle_freeze;
|
||||
mod alt_extend;
|
||||
mod alt_set;
|
||||
mod benchmark;
|
||||
|
|
|
@ -10,7 +10,11 @@ pub struct PerpCancelAllOrders<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -12,7 +12,11 @@ pub struct PerpCancelAllOrdersBySide<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ pub struct PerpCancelOrder<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ pub struct PerpCancelOrderByClientOrderId<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ pub struct PerpDeactivatePosition<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -26,7 +26,8 @@ pub struct PerpLiqBankruptcy<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqor.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// liqor_owner is checked at #1
|
||||
)]
|
||||
pub liqor: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
@ -34,7 +35,8 @@ pub struct PerpLiqBankruptcy<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqee.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub liqee: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
|
|
|
@ -24,13 +24,18 @@ pub struct PerpLiqBasePosition<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqor.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// liqor_owner is checked at #1
|
||||
)]
|
||||
pub liqor: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub liqor_owner: Signer<'info>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = liqee.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub liqee: AccountLoader<'info, MangoAccountFixed>,
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,11 @@ pub struct PerpLiqForceCancelOrders<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
// Allow force cancel even if account is frozen
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
#[account(
|
||||
|
|
|
@ -20,13 +20,18 @@ pub struct PerpLiqQuoteAndBankruptcy<'info> {
|
|||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = liqor.load()?.is_operational() @ MangoError::AccountIsFrozen,
|
||||
// liqor_owner is checked at #1
|
||||
)]
|
||||
pub liqor: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub liqor_owner: Signer<'info>,
|
||||
|
||||
// This account MUST have a loss
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = liqee.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub liqee: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
#[account(mut, has_one = group, has_one = oracle)]
|
||||
|
|
|
@ -16,7 +16,11 @@ pub struct PerpPlaceOrder<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -21,7 +21,11 @@ pub struct PerpSettleFees<'info> {
|
|||
pub perp_market: AccountLoader<'info, PerpMarket>,
|
||||
|
||||
// This account MUST have a loss
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
/// CHECK: Oracle can have different account types, constrained by address in perp_market
|
||||
|
|
|
@ -19,6 +19,7 @@ pub struct PerpSettlePnl<'info> {
|
|||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = settler.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// settler_owner is checked at #1
|
||||
)]
|
||||
pub settler: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
@ -28,10 +29,17 @@ pub struct PerpSettlePnl<'info> {
|
|||
pub perp_market: AccountLoader<'info, PerpMarket>,
|
||||
|
||||
// This account MUST be profitable
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(mut,
|
||||
has_one = group,
|
||||
constraint = account_a.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account_a: AccountLoader<'info, MangoAccountFixed>,
|
||||
// This account MUST have a loss
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account_b.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account_b: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
/// CHECK: Oracle can have different account types, constrained by address in perp_market
|
||||
|
|
|
@ -14,7 +14,8 @@ pub struct Serum3CancelAllOrders<'info> {
|
|||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -20,7 +20,8 @@ pub struct Serum3CancelOrder<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -12,7 +12,8 @@ pub struct Serum3CloseOpenOrders<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -12,7 +12,8 @@ pub struct Serum3CreateOpenOrders<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -19,7 +19,11 @@ pub struct Serum3LiqForceCancelOrders<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
// Allow force cancel even if account is frozen
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
#[account(mut)]
|
||||
|
|
|
@ -142,7 +142,8 @@ pub struct Serum3PlaceOrder<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -20,7 +20,8 @@ pub struct Serum3SettleFunds<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// owner is checked at #1
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
|
|
@ -20,7 +20,11 @@ pub struct TokenDepositIntoExisting<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
#[account(
|
||||
|
@ -53,7 +57,12 @@ pub struct TokenDeposit<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group, has_one = owner)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
has_one = owner,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ pub struct TokenLiqBankruptcy<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqor.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// liqor_owner is checked at #1
|
||||
)]
|
||||
pub liqor: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
@ -36,7 +37,8 @@ pub struct TokenLiqBankruptcy<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqee.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub liqee: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ pub struct TokenLiqWithToken<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqor.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
// liqor_owner is checked at #1
|
||||
)]
|
||||
pub liqor: AccountLoader<'info, MangoAccountFixed>,
|
||||
|
@ -28,7 +29,8 @@ pub struct TokenLiqWithToken<'info> {
|
|||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group
|
||||
has_one = group,
|
||||
constraint = liqee.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub liqee: AccountLoader<'info, MangoAccountFixed>,
|
||||
}
|
||||
|
|
|
@ -20,7 +20,12 @@ pub struct TokenWithdraw<'info> {
|
|||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group, has_one = owner)]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
has_one = owner,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
|
|
|
@ -222,6 +222,10 @@ pub mod mango_v4 {
|
|||
instructions::account_edit(ctx, name_opt, delegate_opt)
|
||||
}
|
||||
|
||||
pub fn aaccount_toggle_freeze(ctx: Context<AccountToggleFreeze>, freeze: bool) -> Result<()> {
|
||||
instructions::account_toggle_freeze(ctx, freeze)
|
||||
}
|
||||
|
||||
pub fn account_close(ctx: Context<AccountClose>, force_close: bool) -> Result<()> {
|
||||
instructions::account_close(ctx, force_close)
|
||||
}
|
||||
|
|
|
@ -86,7 +86,9 @@ pub struct MangoAccount {
|
|||
/// Init health as calculated during HealthReginBegin, rounded up.
|
||||
pub health_region_begin_init_health: i64,
|
||||
|
||||
pub reserved: [u8; 240],
|
||||
pub frozen_until: i64,
|
||||
|
||||
pub reserved: [u8; 232],
|
||||
|
||||
// dynamic
|
||||
pub header_version: u8,
|
||||
|
@ -120,7 +122,8 @@ impl MangoAccount {
|
|||
padding: Default::default(),
|
||||
net_deposits: 0,
|
||||
health_region_begin_init_health: 0,
|
||||
reserved: [0; 240],
|
||||
frozen_until: 0,
|
||||
reserved: [0; 232],
|
||||
header_version: DEFAULT_MANGO_ACCOUNT_VERSION,
|
||||
padding3: Default::default(),
|
||||
padding4: Default::default(),
|
||||
|
@ -201,9 +204,10 @@ pub struct MangoAccountFixed {
|
|||
pub net_deposits: i64,
|
||||
pub perp_spot_transfers: i64,
|
||||
pub health_region_begin_init_health: i64,
|
||||
pub reserved: [u8; 240],
|
||||
pub frozen_until: u64,
|
||||
pub reserved: [u8; 232],
|
||||
}
|
||||
const_assert_eq!(size_of::<MangoAccountFixed>(), 32 * 4 + 8 + 3 * 8 + 240);
|
||||
const_assert_eq!(size_of::<MangoAccountFixed>(), 32 * 4 + 8 + 3 * 8 + 8 + 232);
|
||||
const_assert_eq!(size_of::<MangoAccountFixed>(), 400);
|
||||
const_assert_eq!(size_of::<MangoAccountFixed>() % 8, 0);
|
||||
|
||||
|
@ -214,6 +218,11 @@ impl MangoAccountFixed {
|
|||
.trim_matches(char::from(0))
|
||||
}
|
||||
|
||||
pub fn is_operational(&self) -> bool {
|
||||
let now_ts: u64 = Clock::get().unwrap().unix_timestamp.try_into().unwrap();
|
||||
self.frozen_until < now_ts
|
||||
}
|
||||
|
||||
pub fn is_owner_or_delegate(&self, ix_signer: Pubkey) -> bool {
|
||||
self.owner == ix_signer || self.delegate == ix_signer
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ export class Group {
|
|||
insuranceVault: PublicKey;
|
||||
testing: number;
|
||||
version: number;
|
||||
halted: number;
|
||||
addressLookupTables: PublicKey[];
|
||||
},
|
||||
): Group {
|
||||
|
@ -47,6 +48,7 @@ export class Group {
|
|||
obj.insuranceVault,
|
||||
obj.testing,
|
||||
obj.version,
|
||||
obj.halted,
|
||||
obj.addressLookupTables,
|
||||
[], // addressLookupTablesList
|
||||
new Map(), // banksMapByName
|
||||
|
@ -74,6 +76,7 @@ export class Group {
|
|||
public insuranceVault: PublicKey,
|
||||
public testing: number,
|
||||
public version: number,
|
||||
public halted: number,
|
||||
public addressLookupTables: PublicKey[],
|
||||
public addressLookupTablesList: AddressLookupTableAccount[],
|
||||
public banksMapByName: Map<string, Bank[]>,
|
||||
|
@ -90,6 +93,10 @@ export class Group {
|
|||
public vaultAmountsMap: Map<string, BN>,
|
||||
) {}
|
||||
|
||||
public isOperational(): boolean {
|
||||
return this.halted === 0;
|
||||
}
|
||||
|
||||
public async reloadAll(client: MangoClient, ids?: Id): Promise<void> {
|
||||
// console.time('group.reload');
|
||||
await Promise.all([
|
||||
|
|
|
@ -31,6 +31,7 @@ export class MangoAccount {
|
|||
netDeposits: BN;
|
||||
perpSpotTransfers: BN;
|
||||
healthRegionBeginInitHealth: BN;
|
||||
frozenUntil: BN;
|
||||
headerVersion: number;
|
||||
tokens: unknown;
|
||||
serum3: unknown;
|
||||
|
@ -50,6 +51,7 @@ export class MangoAccount {
|
|||
obj.netDeposits,
|
||||
obj.perpSpotTransfers,
|
||||
obj.healthRegionBeginInitHealth,
|
||||
obj.frozenUntil,
|
||||
obj.headerVersion,
|
||||
obj.tokens as TokenPositionDto[],
|
||||
obj.serum3 as Serum3PositionDto[],
|
||||
|
@ -71,6 +73,7 @@ export class MangoAccount {
|
|||
public netDeposits: BN,
|
||||
public perpSpotTransfers: BN,
|
||||
public healthRegionBeginInitHealth: BN,
|
||||
public frozenUntil: BN,
|
||||
public headerVersion: number,
|
||||
tokens: TokenPositionDto[],
|
||||
serum3: Serum3PositionDto[],
|
||||
|
@ -134,6 +137,10 @@ export class MangoAccount {
|
|||
);
|
||||
}
|
||||
|
||||
public isOperational(): boolean {
|
||||
return this.frozenUntil.lt(new BN(Date.now() / 1000));
|
||||
}
|
||||
|
||||
public tokensActive(): TokenPosition[] {
|
||||
return this.tokens.filter((token) => token.isActive());
|
||||
}
|
||||
|
|
|
@ -671,6 +671,21 @@ export class MangoClient {
|
|||
);
|
||||
}
|
||||
|
||||
public async toggleMangoAccountFreeze(
|
||||
group: Group,
|
||||
mangoAccount: MangoAccount,
|
||||
freeze: boolean,
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.program.methods
|
||||
.aaccountToggleFreeze(freeze)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
account: mangoAccount.publicKey,
|
||||
admin: (this.program.provider as AnchorProvider).wallet.publicKey,
|
||||
})
|
||||
.rpc();
|
||||
}
|
||||
|
||||
public async getMangoAccount(
|
||||
mangoAccount: MangoAccount | PublicKey,
|
||||
): Promise<MangoAccount> {
|
||||
|
|
|
@ -1022,6 +1022,32 @@ export type MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "aaccountToggleFreeze",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "freeze",
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "accountClose",
|
||||
"accounts": [
|
||||
|
@ -4002,12 +4028,16 @@ export type MangoV4 = {
|
|||
],
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "frozenUntil",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "reserved",
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
240
|
||||
232
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -5425,12 +5455,16 @@ export type MangoV4 = {
|
|||
"name": "healthRegionBeginInitHealth",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "frozenUntil",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "reserved",
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
240
|
||||
232
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -7673,6 +7707,11 @@ export type MangoV4 = {
|
|||
"code": 6037,
|
||||
"name": "HasLiquidatableTrustedPerpPnl",
|
||||
"msg": "has liquidatable trusted perp pnl"
|
||||
},
|
||||
{
|
||||
"code": 6038,
|
||||
"name": "AccountIsFrozen",
|
||||
"msg": "account is frozen"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -8701,6 +8740,32 @@ export const IDL: MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "aaccountToggleFreeze",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "freeze",
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "accountClose",
|
||||
"accounts": [
|
||||
|
@ -11681,12 +11746,16 @@ export const IDL: MangoV4 = {
|
|||
],
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "frozenUntil",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "reserved",
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
240
|
||||
232
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -13104,12 +13173,16 @@ export const IDL: MangoV4 = {
|
|||
"name": "healthRegionBeginInitHealth",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "frozenUntil",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "reserved",
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
240
|
||||
232
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -15352,6 +15425,11 @@ export const IDL: MangoV4 = {
|
|||
"code": 6037,
|
||||
"name": "HasLiquidatableTrustedPerpPnl",
|
||||
"msg": "has liquidatable trusted perp pnl"
|
||||
},
|
||||
{
|
||||
"code": 6038,
|
||||
"name": "AccountIsFrozen",
|
||||
"msg": "account is frozen"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue