struct layout reorg + reserved pass (#315)

* reorder structs + review reserved space + split const assets into individual fields for correct checking
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:
microwavedcola1 2022-12-05 15:23:20 +01:00 committed by GitHub
parent fa09c557a1
commit 25312bc398
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 185 additions and 137 deletions

View File

@ -90,44 +90,43 @@ pub fn perp_create_market(
group: ctx.accounts.group.key(),
settle_token_index,
perp_market_index,
group_insurance_fund: if group_insurance_fund { 1 } else { 0 },
trusted_market: if trusted_market { 1 } else { 0 },
trusted_market: u8::from(trusted_market),
group_insurance_fund: u8::from(group_insurance_fund),
bump: *ctx.bumps.get("perp_market").ok_or(MangoError::SomeError)?,
base_decimals,
name: fill_from_str(&name)?,
oracle: ctx.accounts.oracle.key(),
oracle_config: oracle_config.to_oracle_config(),
orderbook: ctx.accounts.orderbook.key(),
event_queue: ctx.accounts.event_queue.key(),
oracle: ctx.accounts.oracle.key(),
oracle_config: oracle_config.to_oracle_config(),
stable_price_model: StablePriceModel::default(),
quote_lot_size,
base_lot_size,
maint_asset_weight: I80F48::from_num(maint_asset_weight),
init_asset_weight: I80F48::from_num(init_asset_weight),
maint_liab_weight: I80F48::from_num(maint_liab_weight),
init_liab_weight: I80F48::from_num(init_liab_weight),
liquidation_fee: I80F48::from_num(liquidation_fee),
maker_fee: I80F48::from_num(maker_fee),
taker_fee: I80F48::from_num(taker_fee),
open_interest: 0,
seq_num: 0,
registration_time: now_ts,
min_funding: I80F48::from_num(min_funding),
max_funding: I80F48::from_num(max_funding),
impact_quantity,
long_funding: I80F48::ZERO,
short_funding: I80F48::ZERO,
funding_last_updated: now_ts,
open_interest: 0,
seq_num: 0,
liquidation_fee: I80F48::from_num(liquidation_fee),
maker_fee: I80F48::from_num(maker_fee),
taker_fee: I80F48::from_num(taker_fee),
fees_accrued: I80F48::ZERO,
fees_settled: I80F48::ZERO,
bump: *ctx.bumps.get("perp_market").ok_or(MangoError::SomeError)?,
base_decimals,
registration_time: now_ts,
padding1: Default::default(),
padding2: Default::default(),
fee_penalty,
settle_fee_flat,
settle_fee_amount_threshold,
settle_fee_fraction_low_health,
stable_price_model: StablePriceModel::default(),
settle_pnl_limit_factor,
settle_pnl_limit_window_size_ts: settle_pnl_limit_window_size_ts,
padding3: Default::default(),
settle_pnl_limit_window_size_ts,
reserved: [0; 1944],
};

View File

@ -72,7 +72,6 @@ pub fn token_edit(
if let Some(oracle_config) = oracle_config_opt.as_ref() {
bank.oracle_config = oracle_config.to_oracle_config();
bank.oracle_conf_filter = bank.oracle_config.conf_filter;
};
if let Some(oracle) = oracle_opt {
bank.oracle = oracle;

View File

@ -113,8 +113,6 @@ pub fn token_register(
oracle: ctx.accounts.oracle.key(),
deposit_index: INDEX_START,
borrow_index: INDEX_START,
cached_indexed_total_deposits: I80F48::ZERO,
cached_indexed_total_borrows: I80F48::ZERO,
indexed_deposits: I80F48::ZERO,
indexed_borrows: I80F48::ZERO,
index_last_updated: now_ts,
@ -142,7 +140,6 @@ pub fn token_register(
bump: *ctx.bumps.get("bank").ok_or(MangoError::SomeError)?,
mint_decimals: ctx.accounts.mint.decimals,
bank_num: 0,
oracle_conf_filter: oracle_config.to_oracle_config().conf_filter,
oracle_config: oracle_config.to_oracle_config(),
stable_price_model: StablePriceModel::default(),
min_vault_to_deposits_ratio,

View File

@ -84,8 +84,6 @@ pub fn token_register_trustless(
oracle: ctx.accounts.oracle.key(),
deposit_index: INDEX_START,
borrow_index: INDEX_START,
cached_indexed_total_deposits: I80F48::ZERO,
cached_indexed_total_borrows: I80F48::ZERO,
indexed_deposits: I80F48::ZERO,
indexed_borrows: I80F48::ZERO,
index_last_updated: now_ts,
@ -113,7 +111,6 @@ pub fn token_register_trustless(
bump: *ctx.bumps.get("bank").ok_or(MangoError::SomeError)?,
mint_decimals: ctx.accounts.mint.decimals,
bank_num: 0,
oracle_conf_filter: I80F48::from_num(0.10),
oracle_config: OracleConfig {
conf_filter: I80F48::from_num(0.10),
max_staleness_slots: -1,

View File

@ -144,9 +144,6 @@ pub fn token_update_index_and_rate(ctx: Context<TokenUpdateIndexAndRate>) -> Res
for ai in ctx.remaining_accounts.iter() {
let mut bank = ai.load_mut::<Bank>()?;
bank.cached_indexed_total_deposits = indexed_total_deposits;
bank.cached_indexed_total_borrows = indexed_total_borrows;
bank.index_last_updated = now_ts;
bank.deposit_index = deposit_index;
@ -154,11 +151,6 @@ pub fn token_update_index_and_rate(ctx: Context<TokenUpdateIndexAndRate>) -> Res
bank.avg_utilization = new_avg_utilization;
// This copies the old conf_filter parameter location to the new one
// inside OracleConfig.
// TODO: remove once fully migrated to OracleConfig
bank.oracle_config.conf_filter = bank.oracle_conf_filter;
bank.stable_price_model = stable_price_model.clone();
}
}

View File

@ -32,20 +32,14 @@ pub struct Bank {
pub vault: Pubkey,
pub oracle: Pubkey,
// TODO: Merge with oracle_config once Bank re-layouts are possible
pub oracle_conf_filter: I80F48,
pub oracle_config: OracleConfig,
pub stable_price_model: StablePriceModel,
/// the index used to scale the value of an IndexedPosition
/// TODO: should always be >= 0, add checks?
pub deposit_index: I80F48,
pub borrow_index: I80F48,
/// total deposits/borrows, only updated during UpdateIndexAndRate
/// TODO: These values could be dropped from the bank, they're written in UpdateIndexAndRate
/// and never read.
pub cached_indexed_total_deposits: I80F48,
pub cached_indexed_total_borrows: I80F48,
/// deposits/borrows for this bank
///
/// Note that these may become negative. It's perfectly fine for users to borrow one one bank
@ -103,10 +97,6 @@ pub struct Bank {
pub bank_num: u32,
pub oracle_config: OracleConfig,
pub stable_price_model: StablePriceModel,
/// Min fraction of deposits that must remain in the vault when borrowing.
pub min_vault_to_deposits_ratio: f64,
@ -139,7 +129,34 @@ pub struct Bank {
#[derivative(Debug = "ignore")]
pub reserved: [u8; 2120],
}
const_assert_eq!(size_of::<Bank>(), 3112);
const_assert_eq!(
size_of::<Bank>(),
32 + 16
+ 32 * 3
+ 96
+ 288
+ 16 * 2
+ 16 * 2
+ 8 * 2
+ 16
+ 16 * 6
+ 16 * 3
+ 16 * 4
+ 16
+ 16
+ 8
+ 8
+ 2
+ 1
+ 1
+ 4
+ 8
+ 8 * 4
+ 8
+ 8
+ 2120
);
const_assert_eq!(size_of::<Bank>(), 3064);
const_assert_eq!(size_of::<Bank>() % 8, 0);
impl Bank {
@ -168,11 +185,8 @@ impl Bank {
group: existing_bank.group,
mint: existing_bank.mint,
oracle: existing_bank.oracle,
oracle_conf_filter: existing_bank.oracle_conf_filter,
deposit_index: existing_bank.deposit_index,
borrow_index: existing_bank.borrow_index,
cached_indexed_total_deposits: existing_bank.cached_indexed_total_deposits,
cached_indexed_total_borrows: existing_bank.cached_indexed_total_borrows,
index_last_updated: existing_bank.index_last_updated,
bank_rate_last_updated: existing_bank.bank_rate_last_updated,
avg_utilization: existing_bank.avg_utilization,
@ -191,7 +205,7 @@ impl Bank {
liquidation_fee: existing_bank.liquidation_fee,
token_index: existing_bank.token_index,
mint_decimals: existing_bank.mint_decimals,
oracle_config: existing_bank.oracle_config.clone(),
oracle_config: existing_bank.oracle_config,
stable_price_model: StablePriceModel::default(),
min_vault_to_deposits_ratio: existing_bank.min_vault_to_deposits_ratio,
net_borrows_limit_quote: existing_bank.net_borrows_limit_quote,
@ -887,7 +901,7 @@ mod tests {
cumulative_borrow_interest: 0.0,
previous_index: I80F48::ZERO,
padding: Default::default(),
reserved: [0; 8],
reserved: [0; 128],
};
account.indexed_position = indexed(I80F48::from_num(start), &bank);

View File

@ -41,6 +41,7 @@ const_assert_eq!(
size_of::<Group>(),
32 * 5 + 4 + 4 + 1 + 1 + 6 + 20 * 32 + 1920
);
const_assert_eq!(size_of::<Group>(), 2736);
const_assert_eq!(size_of::<Group>() % 8, 0);
impl Group {

View File

@ -204,6 +204,7 @@ pub struct MangoAccountFixed {
pub reserved: [u8; 240],
}
const_assert_eq!(size_of::<MangoAccountFixed>(), 32 * 4 + 8 + 3 * 8 + 240);
const_assert_eq!(size_of::<MangoAccountFixed>(), 400);
const_assert_eq!(size_of::<MangoAccountFixed>() % 8, 0);
unsafe impl bytemuck::Pod for MangoAccountFixed {}
@ -627,7 +628,7 @@ impl<
cumulative_borrow_interest: 0.0,
previous_index: I80F48::ZERO,
padding: Default::default(),
reserved: [0; 8],
reserved: [0; 128],
};
}
Ok((v, raw_index, bank_index))

View File

@ -31,10 +31,6 @@ pub struct TokenPosition {
#[derivative(Debug = "ignore")]
pub padding: [u8; 5],
// TODO: When re-layouting: move this to the end
#[derivative(Debug = "ignore")]
pub reserved: [u8; 8],
// bookkeeping variable for onchain interest calculation
// either deposit_index or borrow_index at last indexed_position change
pub previous_index: I80F48,
@ -44,12 +40,19 @@ pub struct TokenPosition {
// (Display only)
// Cumulative borrow interest in token native units
pub cumulative_borrow_interest: f64,
#[derivative(Debug = "ignore")]
pub reserved: [u8; 128],
}
unsafe impl bytemuck::Pod for TokenPosition {}
unsafe impl bytemuck::Zeroable for TokenPosition {}
const_assert_eq!(size_of::<TokenPosition>(), 64);
const_assert_eq!(
size_of::<TokenPosition>(),
16 + 2 + 1 + 5 + 16 + 8 + 8 + 128
);
const_assert_eq!(size_of::<TokenPosition>(), 184);
const_assert_eq!(size_of::<TokenPosition>() % 8, 0);
impl Default for TokenPosition {
@ -62,7 +65,7 @@ impl Default for TokenPosition {
cumulative_borrow_interest: 0.0,
previous_index: I80F48::ZERO,
padding: Default::default(),
reserved: [0; 8],
reserved: [0; 128],
}
}
}
@ -128,6 +131,7 @@ pub struct Serum3Orders {
pub reserved: [u8; 64],
}
const_assert_eq!(size_of::<Serum3Orders>(), 32 + 8 * 2 + 2 * 3 + 2 + 64);
const_assert_eq!(size_of::<Serum3Orders>(), 120);
const_assert_eq!(size_of::<Serum3Orders>() % 8, 0);
unsafe impl bytemuck::Pod for Serum3Orders {}
@ -163,10 +167,11 @@ impl Default for Serum3Orders {
#[derivative(Debug)]
pub struct PerpPosition {
pub market_index: PerpMarketIndex,
#[derivative(Debug = "ignore")]
pub padding: [u8; 2],
pub settle_pnl_limit_window: u32,
pub settle_pnl_limit_settled_in_current_window_native: i64,
/// Active position size, measured in base lots
base_position_lots: i64,
@ -174,8 +179,6 @@ pub struct PerpPosition {
/// measured in native quote
quote_position_native: I80F48,
pub settle_pnl_limit_settled_in_current_window_native: i64,
/// Tracks what the position is to calculate average entry & break even price
pub quote_running_native: i64,
@ -188,9 +191,6 @@ pub struct PerpPosition {
/// Base lots in asks
pub asks_base_lots: i64,
/// Liquidity mining rewards
// pub mngo_accrued: u64,
/// Amount that's on EventQueue waiting to be processed
pub taker_base_lots: i64,
pub taker_quote_lots: i64,
@ -214,10 +214,15 @@ pub struct PerpPosition {
pub avg_entry_price_per_base_lot: f64,
pub realized_pnl_native: I80F48,
// #[derivative(Debug = "ignore")]
// pub reserved: [u8; 8],
#[derivative(Debug = "ignore")]
pub reserved: [u8; 128],
}
const_assert_eq!(size_of::<PerpPosition>(), 176);
const_assert_eq!(
size_of::<PerpPosition>(),
2 + 2 + 4 + 8 + 8 + 16 + 8 + 16 * 2 + 8 * 2 + 8 * 2 + 8 * 5 + 8 + 16 + 128
);
const_assert_eq!(size_of::<PerpPosition>(), 304);
const_assert_eq!(size_of::<PerpPosition>() % 8, 0);
unsafe impl bytemuck::Pod for PerpPosition {}
@ -246,7 +251,7 @@ impl Default for PerpPosition {
realized_pnl_native: I80F48::ZERO,
settle_pnl_limit_window: 0,
settle_pnl_limit_settled_in_current_window_native: 0,
//reserved: Default::default(),
reserved: [0; 128],
}
}
}
@ -493,6 +498,9 @@ pub struct PerpOpenOrder {
pub id: u128,
pub reserved: [u8; 64],
}
const_assert_eq!(size_of::<PerpOpenOrder>(), 1 + 1 + 2 + 4 + 8 + 16 + 64);
const_assert_eq!(size_of::<PerpOpenOrder>(), 96);
const_assert_eq!(size_of::<PerpOpenOrder>() % 8, 0);
impl Default for PerpOpenOrder {
fn default() -> Self {
@ -511,9 +519,6 @@ impl Default for PerpOpenOrder {
unsafe impl bytemuck::Pod for PerpOpenOrder {}
unsafe impl bytemuck::Zeroable for PerpOpenOrder {}
const_assert_eq!(size_of::<PerpOpenOrder>(), 1 + 1 + 2 + 4 + 8 + 16 + 64);
const_assert_eq!(size_of::<PerpOpenOrder>() % 8, 0);
#[macro_export]
macro_rules! account_seeds {
( $account:expr ) => {

View File

@ -34,8 +34,9 @@ pub struct MintInfo {
}
const_assert_eq!(
size_of::<MintInfo>(),
MAX_BANKS * 2 * 32 + 3 * 32 + 2 + 8 + 6 + 2560
32 + 2 + 1 + 5 + 32 + MAX_BANKS * 2 * 32 + 32 + 8 + 2560
);
const_assert_eq!(size_of::<MintInfo>(), 3056);
const_assert_eq!(size_of::<MintInfo>() % 8, 0);
impl MintInfo {

View File

@ -63,6 +63,7 @@ pub struct OracleConfig {
pub max_staleness_slots: i64,
pub reserved: [u8; 72],
}
const_assert_eq!(size_of::<OracleConfig>(), 16 + 8 + 72);
const_assert_eq!(size_of::<OracleConfig>(), 96);
const_assert_eq!(size_of::<OracleConfig>() % 8, 0);
@ -101,6 +102,7 @@ pub struct StubOracle {
pub reserved: [u8; 128],
}
const_assert_eq!(size_of::<StubOracle>(), 32 + 32 + 16 + 8 + 128);
const_assert_eq!(size_of::<StubOracle>(), 216);
const_assert_eq!(size_of::<StubOracle>() % 8, 0);
pub fn determine_oracle_type(acc_info: &impl KeyedAccountReader) -> Result<OracleType> {

View File

@ -19,11 +19,13 @@ const DROP_EXPIRED_ORDER_LIMIT: usize = 5;
pub struct Orderbook {
pub bids: BookSide,
pub asks: BookSide,
pub reserved: [u8; 2400],
}
const_assert_eq!(
std::mem::size_of::<Orderbook>(),
2 * std::mem::size_of::<BookSide>()
2 * std::mem::size_of::<BookSide>() + 2400
);
const_assert_eq!(std::mem::size_of::<Orderbook>(), 495040);
const_assert_eq!(std::mem::size_of::<Orderbook>() % 8, 0);
impl Orderbook {

View File

@ -1,5 +1,6 @@
use anchor_lang::prelude::*;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use static_assertions::const_assert_eq;
use super::*;
@ -31,6 +32,12 @@ pub struct BookSide {
pub fixed: OrderTree,
pub oracle_pegged: OrderTree,
}
const_assert_eq!(
std::mem::size_of::<BookSide>(),
std::mem::size_of::<OrderTree>() * 2
);
const_assert_eq!(std::mem::size_of::<BookSide>(), 246320);
const_assert_eq!(std::mem::size_of::<BookSide>() % 8, 0);
impl BookSide {
/// Iterate over all entries in the book filtering out invalid orders

View File

@ -9,7 +9,7 @@ use static_assertions::const_assert_eq;
use super::order_type::{PostOrderType, Side};
pub type NodeHandle = u32;
const NODE_SIZE: usize = 96;
const NODE_SIZE: usize = 120;
#[derive(IntoPrimitive, TryFromPrimitive)]
#[repr(u32)]
@ -84,10 +84,11 @@ pub struct InnerNode {
/// iterate through the whole bookside.
pub child_earliest_expiry: [u64; 2],
pub reserved: [u8; 48],
pub reserved: [u8; 72],
}
const_assert_eq!(size_of::<InnerNode>() % 8, 0);
const_assert_eq!(size_of::<InnerNode>(), 4 + 4 + 16 + 4 * 2 + 8 * 2 + 72);
const_assert_eq!(size_of::<InnerNode>(), NODE_SIZE);
const_assert_eq!(size_of::<InnerNode>() % 8, 0);
impl InnerNode {
pub fn new(prefix_len: u32, key: u128) -> Self {
@ -143,10 +144,14 @@ pub struct LeafNode {
// Only applicable in the oracle_pegged OrderTree
pub peg_limit: i64,
pub reserved: [u8; 8],
pub reserved: [u8; 32],
}
const_assert_eq!(size_of::<LeafNode>() % 8, 0);
const_assert_eq!(
size_of::<LeafNode>(),
4 + 1 + 1 + 1 + 1 + 16 + 32 + 8 + 8 + 8 + 8 + 32
);
const_assert_eq!(size_of::<LeafNode>(), NODE_SIZE);
const_assert_eq!(size_of::<LeafNode>() % 8, 0);
impl LeafNode {
#[allow(clippy::too_many_arguments)]
@ -173,7 +178,7 @@ impl LeafNode {
client_order_id,
timestamp,
peg_limit,
reserved: [0; 8],
reserved: [0; 32],
}
}
@ -205,15 +210,17 @@ pub struct FreeNode {
pub(crate) next: NodeHandle,
pub(crate) reserved: [u8; NODE_SIZE - 8],
}
const_assert_eq!(size_of::<FreeNode>(), NODE_SIZE);
const_assert_eq!(size_of::<FreeNode>() % 8, 0);
#[zero_copy]
#[derive(Pod)]
pub struct AnyNode {
pub tag: u32,
pub data: [u8; 92], // note: anchor can't parse the struct for IDL when it includes non numbers, NODE_SIZE == 96, 92 == 96 - 4
pub data: [u8; 116],
}
const_assert_eq!(size_of::<AnyNode>(), NODE_SIZE);
const_assert_eq!(size_of::<AnyNode>() % 8, 0);
const_assert_eq!(size_of::<AnyNode>(), size_of::<InnerNode>());
const_assert_eq!(size_of::<AnyNode>(), size_of::<LeafNode>());
const_assert_eq!(size_of::<AnyNode>(), size_of::<FreeNode>());

View File

@ -31,8 +31,6 @@ pub enum OrderTreeType {
/// The key encodes the price in the top 64 bits.
#[zero_copy]
pub struct OrderTree {
// pub meta_data: MetaData,
// todo: do we want this type at this level?
pub order_tree_type: OrderTreeType,
pub padding: [u8; 3],
pub bump_index: u32,
@ -45,8 +43,9 @@ pub struct OrderTree {
}
const_assert_eq!(
std::mem::size_of::<OrderTree>(),
1 + 3 + 4 * 2 + 4 + 4 + 4 + 96 * 1024 + 256 // 98584
1 + 3 + 4 * 2 + 4 + 4 + 4 + 120 * 1024 + 256
);
const_assert_eq!(std::mem::size_of::<OrderTree>(), 123160);
const_assert_eq!(std::mem::size_of::<OrderTree>() % 8, 0);
impl OrderTree {
@ -232,7 +231,7 @@ impl OrderTree {
NodeTag::FreeNode.into()
},
next: self.free_list_head,
reserved: [0; 88],
reserved: [0; 112],
});
self.free_list_len += 1;

View File

@ -26,7 +26,11 @@ pub trait QueueHeader: bytemuck::Pod {
pub struct EventQueue {
pub header: EventQueueHeader,
pub buf: [AnyEvent; MAX_NUM_EVENTS as usize],
pub reserved: [u8; 64],
}
const_assert_eq!(std::mem::size_of::<EventQueue>(), 16 + 488 * 208 + 64);
const_assert_eq!(std::mem::size_of::<EventQueue>(), 101584);
const_assert_eq!(std::mem::size_of::<EventQueue>() % 8, 0);
impl EventQueue {
pub fn len(&self) -> usize {
@ -129,6 +133,8 @@ pub struct EventQueueHeader {
count: u32,
pub seq_num: u64,
}
const_assert_eq!(std::mem::size_of::<EventQueueHeader>(), 16);
const_assert_eq!(std::mem::size_of::<EventQueueHeader>() % 8, 0);
impl QueueHeader for EventQueueHeader {
type Item = AnyEvent;
@ -153,15 +159,12 @@ impl QueueHeader for EventQueueHeader {
}
}
const_assert_eq!(std::mem::size_of::<EventQueue>(), 4 * 2 + 8 + 488 * 208);
const_assert_eq!(std::mem::size_of::<EventQueue>() % 8, 0);
const EVENT_SIZE: usize = 208;
#[zero_copy]
#[derive(Debug, Pod)]
pub struct AnyEvent {
pub event_type: u8,
pub padding: [u8; 207], // note: anchor can't parse the struct for IDL when it includes non numbers, EVENT_SIZE == 208, 207 == 208 - 1
pub padding: [u8; 207],
}
const_assert_eq!(size_of::<AnyEvent>(), EVENT_SIZE);

View File

@ -32,21 +32,22 @@ pub struct PerpMarket {
/// Is this market covered by the group insurance fund?
pub group_insurance_fund: u8,
pub padding1: [u8; 2],
/// PDA bump
pub bump: u8,
pub base_decimals: u8,
pub name: [u8; 16],
pub oracle: Pubkey,
pub oracle_config: OracleConfig,
pub orderbook: Pubkey,
pub event_queue: Pubkey,
pub oracle: Pubkey,
pub oracle_config: OracleConfig,
pub stable_price_model: StablePriceModel,
/// Number of quote native that reresents min tick
pub quote_lot_size: i64,
/// Represents number of base native quantity
/// e.g. if base decimals for underlying asset are 6, base lot size is 100, and base position is 10000, then
/// UI position is 1
@ -59,11 +60,14 @@ pub struct PerpMarket {
pub maint_liab_weight: I80F48,
pub init_liab_weight: I80F48,
// TODO docs
pub liquidation_fee: I80F48,
pub maker_fee: I80F48,
pub taker_fee: I80F48,
pub open_interest: i64,
/// Total number of orders seen
pub seq_num: u64,
pub registration_time: u64,
/// Funding
pub min_funding: I80F48,
pub max_funding: I80F48,
pub impact_quantity: i64,
@ -72,35 +76,17 @@ pub struct PerpMarket {
/// timestamp that funding was last updated in
pub funding_last_updated: u64,
///
pub open_interest: i64,
/// Total number of orders seen
pub seq_num: u64,
/// Fees
pub liquidation_fee: I80F48,
pub maker_fee: I80F48,
pub taker_fee: I80F48,
/// Fees accrued in native quote currency
pub fees_accrued: I80F48,
/// Liquidity mining metadata
/// pub liquidity_mining_info: LiquidityMiningInfo,
/// Token vault which holds mango tokens to be disbursed as liquidity incentives for this perp market
/// pub mngo_vault: Pubkey,
/// PDA bump
pub bump: u8,
pub base_decimals: u8,
pub padding2: [u8; 6],
pub registration_time: u64,
/// Fees settled in native quote currency
pub fees_settled: I80F48,
pub fee_penalty: f32,
// Settling incentives
/// In native units of settlement token, given to each settle call above the
/// settle_fee_amount_threshold.
pub settle_fee_flat: f32,
@ -109,18 +95,49 @@ pub struct PerpMarket {
/// Fraction of pnl to pay out as fee if +pnl account has low health.
pub settle_fee_fraction_low_health: f32,
pub stable_price_model: StablePriceModel,
// Pnl settling limits
/// Fraction of perp base value that can be settled each window.
/// Set to a negative value to disable the limit.
pub settle_pnl_limit_factor: f32,
pub padding3: [u8; 4],
/// Window size in seconds for the perp settlement limit
pub settle_pnl_limit_window_size_ts: u64,
pub reserved: [u8; 1944],
}
const_assert_eq!(size_of::<PerpMarket>(), 2784);
const_assert_eq!(
size_of::<PerpMarket>(),
32 + 2
+ 2
+ 1
+ 1
+ 16
+ 32
+ 32
+ 32
+ 96
+ 288
+ 8
+ 8
+ 16 * 4
+ 8
+ 8
+ 1
+ 1
+ 8
+ 16 * 2
+ 8
+ 16 * 2
+ 8
+ 16 * 5
+ 4
+ 4 * 3
+ 8
+ 8
+ 1944
);
const_assert_eq!(size_of::<PerpMarket>(), 2776);
const_assert_eq!(size_of::<PerpMarket>() % 8, 0);
impl PerpMarket {
@ -285,44 +302,43 @@ impl PerpMarket {
perp_market_index: 0,
trusted_market: 0,
group_insurance_fund: 0,
padding1: Default::default(),
name: Default::default(),
orderbook: Pubkey::new_unique(),
event_queue: Pubkey::new_unique(),
oracle: Pubkey::new_unique(),
oracle_config: OracleConfig {
conf_filter: I80F48::ZERO,
max_staleness_slots: -1,
reserved: [0; 72],
},
orderbook: Pubkey::new_unique(),
event_queue: Pubkey::new_unique(),
stable_price_model: StablePriceModel::default(),
quote_lot_size: 1,
base_lot_size: 1,
maint_asset_weight: I80F48::from(1),
init_asset_weight: I80F48::from(1),
maint_liab_weight: I80F48::from(1),
init_liab_weight: I80F48::from(1),
liquidation_fee: I80F48::ZERO,
maker_fee: I80F48::ZERO,
taker_fee: I80F48::ZERO,
open_interest: 0,
seq_num: 0,
bump: 0,
base_decimals: 0,
registration_time: 0,
min_funding: I80F48::ZERO,
max_funding: I80F48::ZERO,
impact_quantity: 0,
long_funding: I80F48::ZERO,
short_funding: I80F48::ZERO,
funding_last_updated: 0,
open_interest: 0,
seq_num: 0,
liquidation_fee: I80F48::ZERO,
maker_fee: I80F48::ZERO,
taker_fee: I80F48::ZERO,
fees_accrued: I80F48::ZERO,
bump: 0,
base_decimals: 0,
padding2: Default::default(),
registration_time: 0,
fees_settled: I80F48::ZERO,
fee_penalty: 0.0,
settle_fee_flat: 0.0,
settle_fee_amount_threshold: 0.0,
settle_fee_fraction_low_health: 0.0,
stable_price_model: StablePriceModel::default(),
padding3: Default::default(),
settle_pnl_limit_factor: 0.2,
settle_pnl_limit_window_size_ts: 24 * 60 * 60,
reserved: [0; 1944],

View File

@ -34,6 +34,7 @@ const_assert_eq!(
size_of::<Serum3Market>(),
32 + 2 + 2 + 4 + 16 + 2 * 32 + 2 + 1 + 5 + 8 + 128
);
const_assert_eq!(size_of::<Serum3Market>(), 264);
const_assert_eq!(size_of::<Serum3Market>() % 8, 0);
impl Serum3Market {
@ -52,6 +53,7 @@ pub struct Serum3MarketIndexReservation {
pub reserved: [u8; 38],
}
const_assert_eq!(size_of::<Serum3MarketIndexReservation>(), 32 + 2 + 38);
const_assert_eq!(size_of::<Serum3MarketIndexReservation>(), 72);
const_assert_eq!(size_of::<Serum3MarketIndexReservation>() % 8, 0);
#[macro_export]

View File

@ -56,6 +56,10 @@ pub struct StablePriceModel {
#[derivative(Debug = "ignore")]
pub reserved: [u8; 48],
}
const_assert_eq!(
size_of::<StablePriceModel>(),
8 + 8 + 8 * 24 + 8 + 4 + 4 + 4 + 4 + 1 + 7 + 48
);
const_assert_eq!(size_of::<StablePriceModel>(), 288);
const_assert_eq!(size_of::<StablePriceModel>() % 8, 0);