MangoAccount: Rename how tokens/serum3/perps data is stored
token_account_map -> tokens serum3_account_map -> serum3 perp -> perps
This commit is contained in:
parent
c567a2d330
commit
cbc3cc7bbd
|
@ -32,9 +32,9 @@ pub fn create_account(ctx: Context<CreateAccount>, account_num: u8) -> Result<()
|
||||||
group: ctx.accounts.group.key(),
|
group: ctx.accounts.group.key(),
|
||||||
owner: ctx.accounts.owner.key(),
|
owner: ctx.accounts.owner.key(),
|
||||||
delegate: Pubkey::default(),
|
delegate: Pubkey::default(),
|
||||||
token_account_map: TokenAccountMap::new(),
|
tokens: MangoAccountTokens::new(),
|
||||||
serum3_account_map: Serum3AccountMap::new(),
|
serum3: MangoAccountSerum3::new(),
|
||||||
perp: PerpData::new(),
|
perps: MangoAccountPerps::new(),
|
||||||
being_liquidated: 0,
|
being_liquidated: 0,
|
||||||
is_bankrupt: 0,
|
is_bankrupt: 0,
|
||||||
account_num,
|
account_num,
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {
|
||||||
let mut account = ctx.accounts.account.load_mut()?;
|
let mut account = ctx.accounts.account.load_mut()?;
|
||||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||||
|
|
||||||
let (position, position_index) = account.token_account_map.get_mut_or_create(token_index)?;
|
let (position, position_index) = account.tokens.get_mut_or_create(token_index)?;
|
||||||
|
|
||||||
// Update the bank and position
|
// Update the bank and position
|
||||||
let position_is_active = {
|
let position_is_active = {
|
||||||
|
@ -87,7 +87,7 @@ pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {
|
||||||
// Deposits can deactivate a position if they cancel out a previous borrow.
|
// Deposits can deactivate a position if they cancel out a previous borrow.
|
||||||
//
|
//
|
||||||
if !position_is_active {
|
if !position_is_active {
|
||||||
account.token_account_map.deactivate(position_index);
|
account.tokens.deactivate(position_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -75,15 +75,12 @@ pub fn liq_token_with_token(
|
||||||
let liab_price = oracle_price(liab_oracle)?;
|
let liab_price = oracle_price(liab_oracle)?;
|
||||||
|
|
||||||
let liqee_assets_native = liqee
|
let liqee_assets_native = liqee
|
||||||
.token_account_map
|
.tokens
|
||||||
.get(asset_bank.token_index)?
|
.get(asset_bank.token_index)?
|
||||||
.native(&asset_bank);
|
.native(&asset_bank);
|
||||||
require!(liqee_assets_native.is_positive(), MangoError::SomeError);
|
require!(liqee_assets_native.is_positive(), MangoError::SomeError);
|
||||||
|
|
||||||
let liqee_liab_native = liqee
|
let liqee_liab_native = liqee.tokens.get(liab_bank.token_index)?.native(&liab_bank);
|
||||||
.token_account_map
|
|
||||||
.get(liab_bank.token_index)?
|
|
||||||
.native(&liab_bank);
|
|
||||||
require!(liqee_liab_native.is_negative(), MangoError::SomeError);
|
require!(liqee_liab_native.is_negative(), MangoError::SomeError);
|
||||||
|
|
||||||
// TODO why sum of both tokens liquidation fees? Add comment
|
// TODO why sum of both tokens liquidation fees? Add comment
|
||||||
|
@ -121,29 +118,17 @@ pub fn liq_token_with_token(
|
||||||
let asset_transfer = cm!(liab_transfer * liab_price_adjusted / asset_price);
|
let asset_transfer = cm!(liab_transfer * liab_price_adjusted / asset_price);
|
||||||
|
|
||||||
// Apply the balance changes to the liqor and liqee accounts
|
// Apply the balance changes to the liqor and liqee accounts
|
||||||
liab_bank.deposit(
|
liab_bank.deposit(liqee.tokens.get_mut(liab_token_index)?, liab_transfer)?;
|
||||||
liqee.token_account_map.get_mut(liab_token_index)?,
|
|
||||||
liab_transfer,
|
|
||||||
)?;
|
|
||||||
liab_bank.withdraw(
|
liab_bank.withdraw(
|
||||||
liqor
|
liqor.tokens.get_mut_or_create(liab_token_index)?.0,
|
||||||
.token_account_map
|
|
||||||
.get_mut_or_create(liab_token_index)?
|
|
||||||
.0,
|
|
||||||
liab_transfer,
|
liab_transfer,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
asset_bank.deposit(
|
asset_bank.deposit(
|
||||||
liqor
|
liqor.tokens.get_mut_or_create(asset_token_index)?.0,
|
||||||
.token_account_map
|
|
||||||
.get_mut_or_create(asset_token_index)?
|
|
||||||
.0,
|
|
||||||
asset_transfer,
|
|
||||||
)?;
|
|
||||||
asset_bank.withdraw(
|
|
||||||
liqee.token_account_map.get_mut(asset_token_index)?,
|
|
||||||
asset_transfer,
|
asset_transfer,
|
||||||
)?;
|
)?;
|
||||||
|
asset_bank.withdraw(liqee.tokens.get_mut(asset_token_index)?, asset_transfer)?;
|
||||||
|
|
||||||
// Update the health cache
|
// Update the health cache
|
||||||
liqee_health_cache.adjust_token_balance(liab_token_index, liab_transfer)?;
|
liqee_health_cache.adjust_token_balance(liab_token_index, liab_transfer)?;
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn margin_trade<'key, 'accounts, 'remaining, 'info>(
|
||||||
// total number of indexed positions, since
|
// total number of indexed positions, since
|
||||||
// user might end up withdrawing or depositing and activating a new indexed position
|
// user might end up withdrawing or depositing and activating a new indexed position
|
||||||
require!(
|
require!(
|
||||||
banks_len >= account.token_account_map.iter_active().count(),
|
banks_len >= account.tokens.iter_active().count(),
|
||||||
MangoError::SomeError // todo: SomeError
|
MangoError::SomeError // todo: SomeError
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -173,10 +173,7 @@ fn adjust_for_post_cpi_amounts(
|
||||||
let bank_loader = AccountLoader::<'_, Bank>::try_from(bank_ai)?;
|
let bank_loader = AccountLoader::<'_, Bank>::try_from(bank_ai)?;
|
||||||
let mut bank = bank_loader.load_mut()?;
|
let mut bank = bank_loader.load_mut()?;
|
||||||
|
|
||||||
let position = account
|
let position = account.tokens.get_mut_or_create(bank.token_index)?.0;
|
||||||
.token_account_map
|
|
||||||
.get_mut_or_create(bank.token_index)?
|
|
||||||
.0;
|
|
||||||
|
|
||||||
// user has either withdrawn or deposited
|
// user has either withdrawn or deposited
|
||||||
bank.change(
|
bank.change(
|
||||||
|
|
|
@ -50,10 +50,16 @@ pub fn perp_consume_events(ctx: Context<PerpConsumeEvents>, limit: usize) -> Res
|
||||||
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
ma.perp
|
ma.perps.execute_maker(
|
||||||
.execute_maker(perp_market.perp_market_index, &mut perp_market, fill)?;
|
perp_market.perp_market_index,
|
||||||
ma.perp
|
&mut perp_market,
|
||||||
.execute_taker(perp_market.perp_market_index, &mut perp_market, fill)?;
|
fill,
|
||||||
|
)?;
|
||||||
|
ma.perps.execute_taker(
|
||||||
|
perp_market.perp_market_index,
|
||||||
|
&mut perp_market,
|
||||||
|
fill,
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let mut maker = match mango_account_ais.iter().find(|ai| ai.key == &fill.maker)
|
let mut maker = match mango_account_ais.iter().find(|ai| ai.key == &fill.maker)
|
||||||
{
|
{
|
||||||
|
@ -72,12 +78,12 @@ pub fn perp_consume_events(ctx: Context<PerpConsumeEvents>, limit: usize) -> Res
|
||||||
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
maker.perp.execute_maker(
|
maker.perps.execute_maker(
|
||||||
perp_market.perp_market_index,
|
perp_market.perp_market_index,
|
||||||
&mut perp_market,
|
&mut perp_market,
|
||||||
fill,
|
fill,
|
||||||
)?;
|
)?;
|
||||||
taker.perp.execute_taker(
|
taker.perps.execute_taker(
|
||||||
perp_market.perp_market_index,
|
perp_market.perp_market_index,
|
||||||
&mut perp_market,
|
&mut perp_market,
|
||||||
fill,
|
fill,
|
||||||
|
@ -95,7 +101,7 @@ pub fn perp_consume_events(ctx: Context<PerpConsumeEvents>, limit: usize) -> Res
|
||||||
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
ma.perp
|
ma.perps
|
||||||
.remove_order(out.owner_slot as usize, out.quantity)?;
|
.remove_order(out.owner_slot as usize, out.quantity)?;
|
||||||
}
|
}
|
||||||
EventType::Liquidate => {
|
EventType::Liquidate => {
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub fn serum3_cancel_order(
|
||||||
// Validate open_orders
|
// Validate open_orders
|
||||||
require!(
|
require!(
|
||||||
account
|
account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.ok_or_else(|| error!(MangoError::SomeError))?
|
.ok_or_else(|| error!(MangoError::SomeError))?
|
||||||
.open_orders
|
.open_orders
|
||||||
|
|
|
@ -50,9 +50,7 @@ pub fn serum3_create_open_orders(ctx: Context<Serum3CreateOpenOrders>) -> Result
|
||||||
let serum_market = ctx.accounts.serum_market.load()?;
|
let serum_market = ctx.accounts.serum_market.load()?;
|
||||||
let mut account = ctx.accounts.account.load_mut()?;
|
let mut account = ctx.accounts.account.load_mut()?;
|
||||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||||
let serum_account = account
|
let serum_account = account.serum3.create(serum_market.market_index)?;
|
||||||
.serum3_account_map
|
|
||||||
.create(serum_market.market_index)?;
|
|
||||||
serum_account.open_orders = ctx.accounts.open_orders.key();
|
serum_account.open_orders = ctx.accounts.open_orders.key();
|
||||||
serum_account.base_token_index = serum_market.base_token_index;
|
serum_account.base_token_index = serum_market.base_token_index;
|
||||||
serum_account.quote_token_index = serum_market.quote_token_index;
|
serum_account.quote_token_index = serum_market.quote_token_index;
|
||||||
|
@ -61,11 +59,11 @@ pub fn serum3_create_open_orders(ctx: Context<Serum3CreateOpenOrders>) -> Result
|
||||||
// stay permanently blocked. Otherwise users may end up in situations where
|
// stay permanently blocked. Otherwise users may end up in situations where
|
||||||
// they can't settle a market because they don't have free token_account_map!
|
// they can't settle a market because they don't have free token_account_map!
|
||||||
let (quote_position, _) = account
|
let (quote_position, _) = account
|
||||||
.token_account_map
|
.tokens
|
||||||
.get_mut_or_create(serum_market.quote_token_index)?;
|
.get_mut_or_create(serum_market.quote_token_index)?;
|
||||||
quote_position.in_use_count += 1;
|
quote_position.in_use_count += 1;
|
||||||
let (base_position, _) = account
|
let (base_position, _) = account
|
||||||
.token_account_map
|
.tokens
|
||||||
.get_mut_or_create(serum_market.base_token_index)?;
|
.get_mut_or_create(serum_market.base_token_index)?;
|
||||||
base_position.in_use_count += 1;
|
base_position.in_use_count += 1;
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub fn serum3_liq_force_cancel_orders(
|
||||||
// Validate open_orders
|
// Validate open_orders
|
||||||
require!(
|
require!(
|
||||||
account
|
account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.ok_or_else(|| error!(MangoError::SomeError))?
|
.ok_or_else(|| error!(MangoError::SomeError))?
|
||||||
.open_orders
|
.open_orders
|
||||||
|
@ -137,14 +137,14 @@ pub fn serum3_liq_force_cancel_orders(
|
||||||
let mut account = ctx.accounts.account.load_mut()?;
|
let mut account = ctx.accounts.account.load_mut()?;
|
||||||
|
|
||||||
let mut base_bank = ctx.accounts.base_bank.load_mut()?;
|
let mut base_bank = ctx.accounts.base_bank.load_mut()?;
|
||||||
let base_position = account.token_account_map.get_mut(base_bank.token_index)?;
|
let base_position = account.tokens.get_mut(base_bank.token_index)?;
|
||||||
base_bank.change(
|
base_bank.change(
|
||||||
base_position,
|
base_position,
|
||||||
I80F48::from(after_base_vault) - I80F48::from(before_base_vault),
|
I80F48::from(after_base_vault) - I80F48::from(before_base_vault),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut quote_bank = ctx.accounts.quote_bank.load_mut()?;
|
let mut quote_bank = ctx.accounts.quote_bank.load_mut()?;
|
||||||
let quote_position = account.token_account_map.get_mut(quote_bank.token_index)?;
|
let quote_position = account.tokens.get_mut(quote_bank.token_index)?;
|
||||||
quote_bank.change(
|
quote_bank.change(
|
||||||
quote_position,
|
quote_position,
|
||||||
I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault),
|
I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault),
|
||||||
|
|
|
@ -118,7 +118,7 @@ pub fn serum3_place_order(
|
||||||
// Validate open_orders
|
// Validate open_orders
|
||||||
require!(
|
require!(
|
||||||
account
|
account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.ok_or_else(|| error!(MangoError::SomeError))?
|
.ok_or_else(|| error!(MangoError::SomeError))?
|
||||||
.open_orders
|
.open_orders
|
||||||
|
@ -189,14 +189,14 @@ pub fn serum3_place_order(
|
||||||
let mut account = ctx.accounts.account.load_mut()?;
|
let mut account = ctx.accounts.account.load_mut()?;
|
||||||
|
|
||||||
let mut base_bank = ctx.accounts.base_bank.load_mut()?;
|
let mut base_bank = ctx.accounts.base_bank.load_mut()?;
|
||||||
let base_position = account.token_account_map.get_mut(base_bank.token_index)?;
|
let base_position = account.tokens.get_mut(base_bank.token_index)?;
|
||||||
base_bank.change(
|
base_bank.change(
|
||||||
base_position,
|
base_position,
|
||||||
I80F48::from(after_base_vault) - I80F48::from(before_base_vault),
|
I80F48::from(after_base_vault) - I80F48::from(before_base_vault),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut quote_bank = ctx.accounts.quote_bank.load_mut()?;
|
let mut quote_bank = ctx.accounts.quote_bank.load_mut()?;
|
||||||
let quote_position = account.token_account_map.get_mut(quote_bank.token_index)?;
|
let quote_position = account.tokens.get_mut(quote_bank.token_index)?;
|
||||||
quote_bank.change(
|
quote_bank.change(
|
||||||
quote_position,
|
quote_position,
|
||||||
I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault),
|
I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault),
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub fn serum3_settle_funds(ctx: Context<Serum3SettleFunds>) -> Result<()> {
|
||||||
// Validate open_orders
|
// Validate open_orders
|
||||||
require!(
|
require!(
|
||||||
account
|
account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.ok_or_else(|| error!(MangoError::SomeError))?
|
.ok_or_else(|| error!(MangoError::SomeError))?
|
||||||
.open_orders
|
.open_orders
|
||||||
|
@ -124,14 +124,14 @@ pub fn serum3_settle_funds(ctx: Context<Serum3SettleFunds>) -> Result<()> {
|
||||||
let mut account = ctx.accounts.account.load_mut()?;
|
let mut account = ctx.accounts.account.load_mut()?;
|
||||||
|
|
||||||
let mut base_bank = ctx.accounts.base_bank.load_mut()?;
|
let mut base_bank = ctx.accounts.base_bank.load_mut()?;
|
||||||
let base_position = account.token_account_map.get_mut(base_bank.token_index)?;
|
let base_position = account.tokens.get_mut(base_bank.token_index)?;
|
||||||
base_bank.change(
|
base_bank.change(
|
||||||
base_position,
|
base_position,
|
||||||
I80F48::from(after_base_vault) - I80F48::from(before_base_vault),
|
I80F48::from(after_base_vault) - I80F48::from(before_base_vault),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut quote_bank = ctx.accounts.quote_bank.load_mut()?;
|
let mut quote_bank = ctx.accounts.quote_bank.load_mut()?;
|
||||||
let quote_position = account.token_account_map.get_mut(quote_bank.token_index)?;
|
let quote_position = account.tokens.get_mut(quote_bank.token_index)?;
|
||||||
quote_bank.change(
|
quote_bank.change(
|
||||||
quote_position,
|
quote_position,
|
||||||
I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault),
|
I80F48::from(after_quote_vault) - I80F48::from(before_quote_vault),
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub fn withdraw(ctx: Context<Withdraw>, amount: u64, allow_borrow: bool) -> Resu
|
||||||
let mut account = ctx.accounts.account.load_mut()?;
|
let mut account = ctx.accounts.account.load_mut()?;
|
||||||
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
require!(account.is_bankrupt == 0, MangoError::IsBankrupt);
|
||||||
|
|
||||||
let (position, position_index) = account.token_account_map.get_mut_or_create(token_index)?;
|
let (position, position_index) = account.tokens.get_mut_or_create(token_index)?;
|
||||||
|
|
||||||
// The bank will also be passed in remainingAccounts. Use an explicit scope
|
// The bank will also be passed in remainingAccounts. Use an explicit scope
|
||||||
// to drop the &mut before we borrow it immutably again later.
|
// to drop the &mut before we borrow it immutably again later.
|
||||||
|
@ -115,7 +115,7 @@ pub fn withdraw(ctx: Context<Withdraw>, amount: u64, allow_borrow: bool) -> Resu
|
||||||
// deactivated.
|
// deactivated.
|
||||||
//
|
//
|
||||||
if !position_is_active {
|
if !position_is_active {
|
||||||
account.token_account_map.deactivate(position_index);
|
account.tokens.deactivate(position_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -165,8 +165,8 @@ pub fn compute_health_from_fixed_accounts(
|
||||||
health_type: HealthType,
|
health_type: HealthType,
|
||||||
ais: &[AccountInfo],
|
ais: &[AccountInfo],
|
||||||
) -> Result<I80F48> {
|
) -> Result<I80F48> {
|
||||||
let active_token_len = account.token_account_map.iter_active().count();
|
let active_token_len = account.tokens.iter_active().count();
|
||||||
let active_serum_len = account.serum3_account_map.iter_active().count();
|
let active_serum_len = account.serum3.iter_active().count();
|
||||||
let expected_ais = active_token_len * 2 // banks + oracles
|
let expected_ais = active_token_len * 2 // banks + oracles
|
||||||
+ active_serum_len; // open_orders
|
+ active_serum_len; // open_orders
|
||||||
require!(ais.len() == expected_ais, MangoError::SomeError);
|
require!(ais.len() == expected_ais, MangoError::SomeError);
|
||||||
|
@ -298,7 +298,7 @@ fn compute_health_detail<'a, 'b: 'a>(
|
||||||
) -> Result<HealthCache> {
|
) -> Result<HealthCache> {
|
||||||
// token contribution from token accounts
|
// token contribution from token accounts
|
||||||
let mut token_infos = vec![];
|
let mut token_infos = vec![];
|
||||||
for (i, position) in account.token_account_map.iter_active().enumerate() {
|
for (i, position) in account.tokens.iter_active().enumerate() {
|
||||||
let (bank, oracle_ai) =
|
let (bank, oracle_ai) =
|
||||||
retriever.bank_and_oracle(&account.group, i, position.token_index)?;
|
retriever.bank_and_oracle(&account.group, i, position.token_index)?;
|
||||||
let oracle_price = oracle_price(oracle_ai)?;
|
let oracle_price = oracle_price(oracle_ai)?;
|
||||||
|
@ -319,7 +319,7 @@ fn compute_health_detail<'a, 'b: 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// token contribution from serum accounts
|
// token contribution from serum accounts
|
||||||
for (i, serum_account) in account.serum3_account_map.iter_active().enumerate() {
|
for (i, serum_account) in account.serum3.iter_active().enumerate() {
|
||||||
let oo = retriever.serum_oo(i, &serum_account.open_orders)?;
|
let oo = retriever.serum_oo(i, &serum_account.open_orders)?;
|
||||||
if !allow_serum3 {
|
if !allow_serum3 {
|
||||||
require!(
|
require!(
|
||||||
|
|
|
@ -65,17 +65,22 @@ impl TokenAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct TokenAccountMap {
|
pub struct MangoAccountTokens {
|
||||||
pub values: [TokenAccount; MAX_TOKEN_ACCOUNTS],
|
pub values: [TokenAccount; MAX_TOKEN_ACCOUNTS],
|
||||||
}
|
}
|
||||||
|
const_assert_eq!(
|
||||||
|
size_of::<MangoAccountTokens>(),
|
||||||
|
MAX_TOKEN_ACCOUNTS * size_of::<TokenAccount>()
|
||||||
|
);
|
||||||
|
const_assert_eq!(size_of::<MangoAccountTokens>() % 8, 0);
|
||||||
|
|
||||||
impl Default for TokenAccountMap {
|
impl Default for MangoAccountTokens {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenAccountMap {
|
impl MangoAccountTokens {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
values: [TokenAccount {
|
values: [TokenAccount {
|
||||||
|
@ -186,17 +191,22 @@ impl Default for Serum3Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct Serum3AccountMap {
|
pub struct MangoAccountSerum3 {
|
||||||
pub values: [Serum3Account; MAX_SERUM3_ACCOUNTS],
|
pub values: [Serum3Account; MAX_SERUM3_ACCOUNTS],
|
||||||
}
|
}
|
||||||
|
const_assert_eq!(
|
||||||
|
size_of::<MangoAccountSerum3>(),
|
||||||
|
MAX_SERUM3_ACCOUNTS * size_of::<Serum3Account>()
|
||||||
|
);
|
||||||
|
const_assert_eq!(size_of::<MangoAccountSerum3>() % 8, 0);
|
||||||
|
|
||||||
impl Default for Serum3AccountMap {
|
impl Default for MangoAccountSerum3 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serum3AccountMap {
|
impl MangoAccountSerum3 {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
values: [Serum3Account::default(); MAX_SERUM3_ACCOUNTS],
|
values: [Serum3Account::default(); MAX_SERUM3_ACCOUNTS],
|
||||||
|
@ -308,7 +318,7 @@ impl PerpAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct PerpData {
|
pub struct MangoAccountPerps {
|
||||||
pub accounts: [PerpAccount; MAX_PERP_ACCOUNTS],
|
pub accounts: [PerpAccount; MAX_PERP_ACCOUNTS],
|
||||||
|
|
||||||
// TODO: possibly it's more convenient to store a single list of PerpOpenOrder structs?
|
// TODO: possibly it's more convenient to store a single list of PerpOpenOrder structs?
|
||||||
|
@ -318,12 +328,12 @@ pub struct PerpData {
|
||||||
pub order_client_id: [u64; MAX_PERP_OPEN_ORDERS],
|
pub order_client_id: [u64; MAX_PERP_OPEN_ORDERS],
|
||||||
}
|
}
|
||||||
const_assert_eq!(
|
const_assert_eq!(
|
||||||
size_of::<PerpData>(),
|
size_of::<MangoAccountPerps>(),
|
||||||
MAX_PERP_ACCOUNTS * size_of::<PerpAccount>() + MAX_PERP_OPEN_ORDERS * (2 + 1 + 16 + 8)
|
MAX_PERP_ACCOUNTS * size_of::<PerpAccount>() + MAX_PERP_OPEN_ORDERS * (2 + 1 + 16 + 8)
|
||||||
);
|
);
|
||||||
const_assert_eq!(size_of::<PerpData>() % 8, 0);
|
const_assert_eq!(size_of::<MangoAccountPerps>() % 8, 0);
|
||||||
|
|
||||||
impl PerpData {
|
impl MangoAccountPerps {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
accounts: [PerpAccount::default(); MAX_PERP_ACCOUNTS],
|
accounts: [PerpAccount::default(); MAX_PERP_ACCOUNTS],
|
||||||
|
@ -491,7 +501,7 @@ impl PerpData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PerpData {
|
impl Default for MangoAccountPerps {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
|
@ -507,13 +517,13 @@ pub struct MangoAccount {
|
||||||
|
|
||||||
// Maps token_index -> deposit/borrow account for each token
|
// Maps token_index -> deposit/borrow account for each token
|
||||||
// that is active on this MangoAccount.
|
// that is active on this MangoAccount.
|
||||||
pub token_account_map: TokenAccountMap,
|
pub tokens: MangoAccountTokens,
|
||||||
|
|
||||||
// Maps serum_market_index -> open orders for each serum market
|
// Maps serum_market_index -> open orders for each serum market
|
||||||
// that is active on this MangoAccount.
|
// that is active on this MangoAccount.
|
||||||
pub serum3_account_map: Serum3AccountMap,
|
pub serum3: MangoAccountSerum3,
|
||||||
|
|
||||||
pub perp: PerpData,
|
pub perps: MangoAccountPerps,
|
||||||
|
|
||||||
/// This account cannot open new positions or borrow until `init_health >= 0`
|
/// This account cannot open new positions or borrow until `init_health >= 0`
|
||||||
pub being_liquidated: u8,
|
pub being_liquidated: u8,
|
||||||
|
@ -530,9 +540,9 @@ pub struct MangoAccount {
|
||||||
const_assert_eq!(
|
const_assert_eq!(
|
||||||
size_of::<MangoAccount>(),
|
size_of::<MangoAccount>(),
|
||||||
3 * 32
|
3 * 32
|
||||||
+ MAX_TOKEN_ACCOUNTS * size_of::<TokenAccount>()
|
+ size_of::<MangoAccountTokens>()
|
||||||
+ MAX_SERUM3_ACCOUNTS * size_of::<Serum3Account>()
|
+ size_of::<MangoAccountSerum3>()
|
||||||
+ size_of::<PerpData>()
|
+ size_of::<MangoAccountPerps>()
|
||||||
+ 4
|
+ 4
|
||||||
+ 4
|
+ 4
|
||||||
);
|
);
|
||||||
|
|
|
@ -336,7 +336,7 @@ impl<'a> Book<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner_slot = mango_account
|
let owner_slot = mango_account
|
||||||
.perp
|
.perps
|
||||||
.next_order_slot()
|
.next_order_slot()
|
||||||
.ok_or_else(|| error!(MangoError::SomeError))?;
|
.ok_or_else(|| error!(MangoError::SomeError))?;
|
||||||
let new_order = LeafNode::new(
|
let new_order = LeafNode::new(
|
||||||
|
@ -397,7 +397,7 @@ fn apply_fees(
|
||||||
|
|
||||||
let taker_fees = taker_quote_native * market.taker_fee;
|
let taker_fees = taker_quote_native * market.taker_fee;
|
||||||
let perp_account = mango_account
|
let perp_account = mango_account
|
||||||
.perp
|
.perps
|
||||||
.get_account_mut_or_create(market.perp_market_index)?
|
.get_account_mut_or_create(market.perp_market_index)?
|
||||||
.0;
|
.0;
|
||||||
perp_account.quote_position_native -= taker_fees;
|
perp_account.quote_position_native -= taker_fees;
|
||||||
|
|
|
@ -110,7 +110,7 @@ async fn derive_health_check_remaining_account_metas(
|
||||||
// figure out all the banks/oracles that need to be passed for the health check
|
// figure out all the banks/oracles that need to be passed for the health check
|
||||||
let mut banks = vec![];
|
let mut banks = vec![];
|
||||||
let mut oracles = vec![];
|
let mut oracles = vec![];
|
||||||
for position in account.token_account_map.iter_active() {
|
for position in account.tokens.iter_active() {
|
||||||
let mint_info =
|
let mint_info =
|
||||||
get_mint_info_by_token_index(account_loader, account, position.token_index).await;
|
get_mint_info_by_token_index(account_loader, account, position.token_index).await;
|
||||||
// TODO: ALTs are unavailable
|
// TODO: ALTs are unavailable
|
||||||
|
@ -129,7 +129,7 @@ async fn derive_health_check_remaining_account_metas(
|
||||||
// If there is not yet an active position for the token, we need to pass
|
// If there is not yet an active position for the token, we need to pass
|
||||||
// the bank/oracle for health check anyway.
|
// the bank/oracle for health check anyway.
|
||||||
let new_position = account
|
let new_position = account
|
||||||
.token_account_map
|
.tokens
|
||||||
.values
|
.values
|
||||||
.iter()
|
.iter()
|
||||||
.position(|p| !p.is_active())
|
.position(|p| !p.is_active())
|
||||||
|
@ -140,10 +140,7 @@ async fn derive_health_check_remaining_account_metas(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let serum_oos = account
|
let serum_oos = account.serum3.iter_active().map(|&s| s.open_orders);
|
||||||
.serum3_account_map
|
|
||||||
.iter_active()
|
|
||||||
.map(|&s| s.open_orders);
|
|
||||||
|
|
||||||
banks
|
banks
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -175,9 +172,9 @@ async fn derive_liquidation_remaining_account_metas(
|
||||||
let mut banks = vec![];
|
let mut banks = vec![];
|
||||||
let mut oracles = vec![];
|
let mut oracles = vec![];
|
||||||
let token_indexes = liqee
|
let token_indexes = liqee
|
||||||
.token_account_map
|
.tokens
|
||||||
.iter_active()
|
.iter_active()
|
||||||
.chain(liqor.token_account_map.iter_active())
|
.chain(liqor.tokens.iter_active())
|
||||||
.map(|ta| ta.token_index)
|
.map(|ta| ta.token_index)
|
||||||
.unique();
|
.unique();
|
||||||
for token_index in token_indexes {
|
for token_index in token_indexes {
|
||||||
|
@ -199,9 +196,9 @@ async fn derive_liquidation_remaining_account_metas(
|
||||||
}
|
}
|
||||||
|
|
||||||
let serum_oos = liqee
|
let serum_oos = liqee
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.iter_active()
|
.iter_active()
|
||||||
.chain(liqor.serum3_account_map.iter_active())
|
.chain(liqor.serum3.iter_active())
|
||||||
.map(|&s| s.open_orders);
|
.map(|&s| s.open_orders);
|
||||||
|
|
||||||
banks
|
banks
|
||||||
|
@ -232,7 +229,7 @@ pub async fn account_position(solana: &SolanaCookie, account: Pubkey, bank: Pubk
|
||||||
let account_data: MangoAccount = solana.get_account(account).await;
|
let account_data: MangoAccount = solana.get_account(account).await;
|
||||||
let bank_data: Bank = solana.get_account(bank).await;
|
let bank_data: Bank = solana.get_account(bank).await;
|
||||||
let native = account_data
|
let native = account_data
|
||||||
.token_account_map
|
.tokens
|
||||||
.find(bank_data.token_index)
|
.find(bank_data.token_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.native(&bank_data);
|
.native(&bank_data);
|
||||||
|
@ -266,7 +263,7 @@ impl<'keypair> ClientInstruction for MarginTradeInstruction<'keypair> {
|
||||||
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
||||||
|
|
||||||
let instruction = Self::Instruction {
|
let instruction = Self::Instruction {
|
||||||
banks_len: account.token_account_map.iter_active().count(),
|
banks_len: account.tokens.iter_active().count(),
|
||||||
cpi_data: self.margin_trade_program_ix_cpi_data.clone(),
|
cpi_data: self.margin_trade_program_ix_cpi_data.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -876,7 +873,7 @@ impl<'keypair> ClientInstruction for Serum3PlaceOrderInstruction<'keypair> {
|
||||||
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
||||||
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
||||||
let open_orders = account
|
let open_orders = account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.open_orders;
|
.open_orders;
|
||||||
|
@ -971,7 +968,7 @@ impl<'keypair> ClientInstruction for Serum3CancelOrderInstruction<'keypair> {
|
||||||
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
||||||
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
||||||
let open_orders = account
|
let open_orders = account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.open_orders;
|
.open_orders;
|
||||||
|
@ -1030,7 +1027,7 @@ impl<'keypair> ClientInstruction for Serum3SettleFundsInstruction<'keypair> {
|
||||||
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
||||||
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
||||||
let open_orders = account
|
let open_orders = account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.open_orders;
|
.open_orders;
|
||||||
|
@ -1104,7 +1101,7 @@ impl ClientInstruction for Serum3LiqForceCancelOrdersInstruction {
|
||||||
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
|
||||||
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
let serum_market: Serum3Market = account_loader.load(&self.serum_market).await.unwrap();
|
||||||
let open_orders = account
|
let open_orders = account
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.find(serum_market.market_index)
|
.find(serum_market.market_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.open_orders;
|
.open_orders;
|
||||||
|
|
|
@ -84,7 +84,7 @@ async fn test_margin_trade() -> Result<(), TransportError> {
|
||||||
let account_data: MangoAccount = solana.get_account(account).await;
|
let account_data: MangoAccount = solana.get_account(account).await;
|
||||||
let bank_data: Bank = solana.get_account(bank).await;
|
let bank_data: Bank = solana.get_account(bank).await;
|
||||||
assert!(
|
assert!(
|
||||||
account_data.token_account_map.values[0].native(&bank_data)
|
account_data.tokens.values[0].native(&bank_data)
|
||||||
- I80F48::from_num(deposit_amount_initial)
|
- I80F48::from_num(deposit_amount_initial)
|
||||||
< dust_threshold
|
< dust_threshold
|
||||||
);
|
);
|
||||||
|
|
|
@ -120,7 +120,7 @@ async fn test_position_lifetime() -> Result<()> {
|
||||||
|
|
||||||
// Check that positions are fully deactivated
|
// Check that positions are fully deactivated
|
||||||
let account: MangoAccount = solana.get_account(account).await;
|
let account: MangoAccount = solana.get_account(account).await;
|
||||||
assert_eq!(account.token_account_map.iter_active().count(), 0);
|
assert_eq!(account.tokens.iter_active().count(), 0);
|
||||||
|
|
||||||
// No user tokens got lost
|
// No user tokens got lost
|
||||||
for &payer_token in payer_mint_accounts {
|
for &payer_token in payer_mint_accounts {
|
||||||
|
@ -199,7 +199,7 @@ async fn test_position_lifetime() -> Result<()> {
|
||||||
|
|
||||||
// Check that positions are fully deactivated
|
// Check that positions are fully deactivated
|
||||||
let account: MangoAccount = solana.get_account(account).await;
|
let account: MangoAccount = solana.get_account(account).await;
|
||||||
assert_eq!(account.token_account_map.iter_active().count(), 0);
|
assert_eq!(account.tokens.iter_active().count(), 0);
|
||||||
|
|
||||||
// No user tokens got lost
|
// No user tokens got lost
|
||||||
for &payer_token in payer_mint_accounts {
|
for &payer_token in payer_mint_accounts {
|
||||||
|
|
|
@ -127,7 +127,7 @@ async fn test_serum() -> Result<(), TransportError> {
|
||||||
let account_data: MangoAccount = solana.get_account(account).await;
|
let account_data: MangoAccount = solana.get_account(account).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
account_data
|
account_data
|
||||||
.serum3_account_map
|
.serum3
|
||||||
.iter_active()
|
.iter_active()
|
||||||
.map(|v| (v.open_orders, v.market_index))
|
.map(|v| (v.open_orders, v.market_index))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
|
Loading…
Reference in New Issue