Rearrange MangoAccount to avoid padding bytes
This commit is contained in:
parent
5470dc998a
commit
9cf4f1a748
|
@ -39,11 +39,11 @@ pub fn create_account(ctx: Context<CreateAccount>, account_num: u8) -> Result<()
|
|||
order_side: [Side::Bid; MAX_PERP_OPEN_ORDERS],
|
||||
orders: [i128::MAX; MAX_PERP_OPEN_ORDERS],
|
||||
client_order_ids: [u64::MAX; MAX_PERP_OPEN_ORDERS],
|
||||
being_liquidated: false,
|
||||
is_bankrupt: false,
|
||||
being_liquidated: 0,
|
||||
is_bankrupt: 0,
|
||||
account_num,
|
||||
bump: *ctx.bumps.get("account").ok_or(MangoError::SomeError)?,
|
||||
reserved: [0; 5],
|
||||
reserved: [0; 4],
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -56,7 +56,7 @@ pub fn deposit(ctx: Context<Deposit>, 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);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
|
||||
let (position, position_index) = account.token_account_map.get_mut_or_create(token_index)?;
|
||||
|
||||
|
|
|
@ -38,24 +38,24 @@ 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);
|
||||
require!(liqor.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
|
||||
let mut liqee = ctx.accounts.liqee.load_mut()?;
|
||||
require!(!liqee.is_bankrupt, MangoError::IsBankrupt);
|
||||
require!(liqee.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
|
||||
// Initial liqee health check
|
||||
let mut liqee_health_cache = health_cache_for_liqee(&liqee, &account_retriever)?;
|
||||
let init_health = liqee_health_cache.health(HealthType::Init)?;
|
||||
if liqee.being_liquidated {
|
||||
if liqee.being_liquidated != 0 {
|
||||
if init_health > I80F48::ZERO {
|
||||
liqee.being_liquidated = false;
|
||||
liqee.being_liquidated = 0;
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
let maint_health = liqee_health_cache.health(HealthType::Maint)?;
|
||||
require!(maint_health < I80F48::ZERO, MangoError::SomeError);
|
||||
liqee.being_liquidated = true;
|
||||
liqee.being_liquidated = 1;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -165,7 +165,7 @@ pub fn liq_token_with_token(
|
|||
|
||||
// this is equivalent to one native USDC or 1e-6 USDC
|
||||
// This is used as threshold to flip flag instead of 0 because of dust issues
|
||||
liqee.being_liquidated = init_health < -I80F48::ONE;
|
||||
liqee.being_liquidated = if init_health < -I80F48::ONE { 1 } else { 0 };
|
||||
}
|
||||
|
||||
// Check liqor's health
|
||||
|
|
|
@ -27,7 +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);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
|
||||
// remaining_accounts layout is expected as follows
|
||||
// * banks_len number of banks
|
||||
|
|
|
@ -51,7 +51,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);
|
||||
require!(mango_account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
let mango_account_pk = ctx.accounts.account.key();
|
||||
|
||||
let mut perp_market = ctx.accounts.perp_market.load_mut()?;
|
||||
|
|
|
@ -95,7 +95,7 @@ pub fn serum3_cancel_order(
|
|||
//
|
||||
{
|
||||
let account = ctx.accounts.account.load()?;
|
||||
require!(!account.is_bankrupt, MangoError::IsBankrupt);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
|
||||
let serum_market = ctx.accounts.serum_market.load()?;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ pub fn serum3_create_open_orders(ctx: Context<Serum3CreateOpenOrders>) -> Result
|
|||
|
||||
let serum_market = ctx.accounts.serum_market.load()?;
|
||||
let mut account = ctx.accounts.account.load_mut()?;
|
||||
require!(!account.is_bankrupt, MangoError::IsBankrupt);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
let serum_account = account
|
||||
.serum3_account_map
|
||||
.create(serum_market.market_index)?;
|
||||
|
|
|
@ -65,7 +65,7 @@ pub fn serum3_liq_force_cancel_orders(
|
|||
//
|
||||
{
|
||||
let account = ctx.accounts.account.load()?;
|
||||
require!(!account.is_bankrupt, MangoError::IsBankrupt);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
let serum_market = ctx.accounts.serum_market.load()?;
|
||||
|
||||
// Validate open_orders
|
||||
|
|
|
@ -157,7 +157,7 @@ pub fn serum3_place_order(
|
|||
//
|
||||
{
|
||||
let account = ctx.accounts.account.load()?;
|
||||
require!(!account.is_bankrupt, MangoError::IsBankrupt);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
let serum_market = ctx.accounts.serum_market.load()?;
|
||||
|
||||
// Validate open_orders
|
||||
|
|
|
@ -64,7 +64,7 @@ pub fn serum3_settle_funds(ctx: Context<Serum3SettleFunds>) -> Result<()> {
|
|||
//
|
||||
{
|
||||
let account = ctx.accounts.account.load()?;
|
||||
require!(!account.is_bankrupt, MangoError::IsBankrupt);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
let serum_market = ctx.accounts.serum_market.load()?;
|
||||
|
||||
// Validate open_orders
|
||||
|
|
|
@ -58,7 +58,7 @@ pub fn withdraw(ctx: Context<Withdraw>, 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);
|
||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||
|
||||
let (position, position_index) = account.token_account_map.get_mut_or_create(token_index)?;
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ mod tests {
|
|||
indexed_value: I80F48::ZERO,
|
||||
token_index: 0,
|
||||
in_use_count: if is_in_use { 1 } else { 0 },
|
||||
reserved: [0; 5],
|
||||
};
|
||||
|
||||
account.indexed_value = indexed(I80F48::from_num(start), &bank);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use fixed::types::I80F48;
|
||||
use static_assertions::const_assert_eq;
|
||||
use std::mem::size_of;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::state::*;
|
||||
|
@ -33,8 +35,11 @@ pub struct TokenAccount {
|
|||
|
||||
/// incremented when a market requires this position to stay alive
|
||||
pub in_use_count: u8,
|
||||
|
||||
pub reserved: [u8; 5],
|
||||
}
|
||||
// TODO: static assert the size and alignment
|
||||
const_assert_eq!(size_of::<TokenAccount>(), 24);
|
||||
const_assert_eq!(size_of::<TokenAccount>() % 8, 0);
|
||||
|
||||
impl TokenAccount {
|
||||
pub fn is_active(&self) -> bool {
|
||||
|
@ -76,6 +81,7 @@ impl TokenAccountMap {
|
|||
indexed_value: I80F48::ZERO,
|
||||
token_index: TokenIndex::MAX,
|
||||
in_use_count: 0,
|
||||
reserved: [0; 5],
|
||||
}; MAX_INDEXED_POSITIONS],
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +118,7 @@ impl TokenAccountMap {
|
|||
indexed_value: I80F48::ZERO,
|
||||
token_index,
|
||||
in_use_count: 0,
|
||||
reserved: [0; 5],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -149,8 +156,11 @@ pub struct Serum3Account {
|
|||
/// uses and look up the correct oracles.
|
||||
pub base_token_index: TokenIndex,
|
||||
pub quote_token_index: TokenIndex,
|
||||
|
||||
pub reserved: [u8; 2],
|
||||
}
|
||||
// TODO: static assert the size and alignment
|
||||
const_assert_eq!(size_of::<Serum3Account>(), 40);
|
||||
const_assert_eq!(size_of::<Serum3Account>() % 8, 0);
|
||||
|
||||
impl Serum3Account {
|
||||
pub fn is_active(&self) -> bool {
|
||||
|
@ -169,6 +179,7 @@ impl Default for Serum3Account {
|
|||
market_index: Serum3MarketIndex::MAX,
|
||||
base_token_index: TokenIndex::MAX,
|
||||
quote_token_index: TokenIndex::MAX,
|
||||
reserved: [0; 2],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,6 +235,7 @@ impl Serum3AccountMap {
|
|||
#[zero_copy]
|
||||
pub struct PerpAccount {
|
||||
pub market_index: PerpMarketIndex,
|
||||
pub reserved: [u8; 6],
|
||||
|
||||
/// Active position size, measured in base lots
|
||||
pub base_position: i64,
|
||||
|
@ -248,6 +260,8 @@ pub struct PerpAccount {
|
|||
pub taker_base: i64,
|
||||
pub taker_quote: i64,
|
||||
}
|
||||
const_assert_eq!(size_of::<PerpAccount>(), 8 + 8 * 5 + 16);
|
||||
const_assert_eq!(size_of::<PerpAccount>() % 8, 0);
|
||||
|
||||
impl Default for PerpAccount {
|
||||
fn default() -> Self {
|
||||
|
@ -259,6 +273,7 @@ impl Default for PerpAccount {
|
|||
asks_quantity: 0,
|
||||
taker_base: 0,
|
||||
taker_quote: 0,
|
||||
reserved: [0; 6],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,18 +386,28 @@ pub struct MangoAccount {
|
|||
pub client_order_ids: [u64; MAX_PERP_OPEN_ORDERS],
|
||||
|
||||
/// This account cannot open new positions or borrow until `init_health >= 0`
|
||||
pub being_liquidated: bool, // TODO: for strict Pod compat, these should be u8, not bool
|
||||
pub being_liquidated: u8,
|
||||
|
||||
/// This account cannot do anything except go through `resolve_bankruptcy`
|
||||
pub is_bankrupt: bool,
|
||||
pub is_bankrupt: u8,
|
||||
|
||||
pub account_num: u8,
|
||||
pub bump: u8,
|
||||
|
||||
// pub info: [u8; INFO_LEN], // TODO: Info could be in a separate PDA?
|
||||
pub reserved: [u8; 5],
|
||||
pub reserved: [u8; 4],
|
||||
}
|
||||
// TODO: static assert the size and alignment
|
||||
const_assert_eq!(
|
||||
size_of::<MangoAccount>(),
|
||||
3 * 32
|
||||
+ MAX_INDEXED_POSITIONS * size_of::<TokenAccount>()
|
||||
+ MAX_SERUM_OPEN_ORDERS * size_of::<Serum3Account>()
|
||||
+ MAX_PERP_OPEN_ORDERS * size_of::<PerpAccount>()
|
||||
+ MAX_PERP_OPEN_ORDERS * (2 + 1 + 16 + 8)
|
||||
+ 4
|
||||
+ 4
|
||||
);
|
||||
const_assert_eq!(size_of::<MangoAccount>() % 8, 0);
|
||||
|
||||
impl MangoAccount {
|
||||
pub fn next_order_slot(&self) -> Option<usize> {
|
||||
|
|
|
@ -374,7 +374,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
0
|
||||
);
|
||||
let liqee: MangoAccount = solana.get_account(account).await;
|
||||
assert!(liqee.being_liquidated);
|
||||
assert_eq!(liqee.being_liquidated, 1);
|
||||
|
||||
//
|
||||
// TEST: liquidate the remaining borrow2 against collateral1,
|
||||
|
@ -404,7 +404,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
1000 - 32
|
||||
);
|
||||
let liqee: MangoAccount = solana.get_account(account).await;
|
||||
assert!(liqee.being_liquidated);
|
||||
assert_eq!(liqee.being_liquidated, 1);
|
||||
|
||||
//
|
||||
// TEST: liquidate borrow1 with collateral1, but place a limit
|
||||
|
@ -433,7 +433,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
1000 - 32 - 21
|
||||
);
|
||||
let liqee: MangoAccount = solana.get_account(account).await;
|
||||
assert!(liqee.being_liquidated);
|
||||
assert_eq!(liqee.being_liquidated, 1);
|
||||
|
||||
//
|
||||
// TEST: liquidate borrow1 with collateral1, making the account healthy again
|
||||
|
@ -464,7 +464,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
1000 - 32 - 535
|
||||
);
|
||||
let liqee: MangoAccount = solana.get_account(account).await;
|
||||
assert!(!liqee.being_liquidated);
|
||||
assert_eq!(liqee.being_liquidated, 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue