Rename MangoAccount components
This commit is contained in:
parent
743f650494
commit
648b462352
|
@ -35,9 +35,9 @@ pub fn create_account(ctx: Context<CreateAccount>, account_num: u8, name: String
|
||||||
account.account_num = account_num;
|
account.account_num = account_num;
|
||||||
account.bump = *ctx.bumps.get("account").ok_or(MangoError::SomeError)?;
|
account.bump = *ctx.bumps.get("account").ok_or(MangoError::SomeError)?;
|
||||||
account.delegate = Pubkey::default();
|
account.delegate = Pubkey::default();
|
||||||
account.tokens = MangoAccountTokens::default();
|
account.tokens = MangoAccountTokenPositions::default();
|
||||||
account.serum3 = MangoAccountSerum3::default();
|
account.serum3 = MangoAccountSerum3Orders::default();
|
||||||
account.perps = MangoAccountPerps::default();
|
account.perps = MangoAccountPerpPositions::default();
|
||||||
account.being_liquidated = 0;
|
account.being_liquidated = 0;
|
||||||
account.is_bankrupt = 0;
|
account.is_bankrupt = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{OracleConfig, TokenAccount, TokenIndex};
|
use super::{OracleConfig, TokenPosition, TokenIndex};
|
||||||
use crate::error::MangoError;
|
use crate::error::MangoError;
|
||||||
use crate::util::checked_math as cm;
|
use crate::util::checked_math as cm;
|
||||||
use anchor_lang::prelude::*;
|
use anchor_lang::prelude::*;
|
||||||
|
@ -126,7 +126,7 @@ impl Bank {
|
||||||
/// fractional deposits can be relevant during liquidation, for example
|
/// fractional deposits can be relevant during liquidation, for example
|
||||||
pub fn deposit(
|
pub fn deposit(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
mut native_amount: I80F48,
|
mut native_amount: I80F48,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
require!(native_amount >= 0, MangoError::SomeError);
|
require!(native_amount >= 0, MangoError::SomeError);
|
||||||
|
@ -136,24 +136,24 @@ impl Bank {
|
||||||
let new_native_position = cm!(native_position + native_amount);
|
let new_native_position = cm!(native_position + native_amount);
|
||||||
let indexed_change = cm!(native_amount / self.borrow_index + I80F48::DELTA);
|
let indexed_change = cm!(native_amount / self.borrow_index + I80F48::DELTA);
|
||||||
// this is only correct if it's not positive, because it scales the whole amount by borrow_index
|
// this is only correct if it's not positive, because it scales the whole amount by borrow_index
|
||||||
let new_indexed_value = cm!(position.indexed_value + indexed_change);
|
let new_indexed_value = cm!(position.indexed_position + indexed_change);
|
||||||
if new_indexed_value.is_negative() {
|
if new_indexed_value.is_negative() {
|
||||||
// pay back borrows only, leaving a negative position
|
// pay back borrows only, leaving a negative position
|
||||||
self.indexed_total_borrows = cm!(self.indexed_total_borrows - indexed_change);
|
self.indexed_total_borrows = cm!(self.indexed_total_borrows - indexed_change);
|
||||||
position.indexed_value = new_indexed_value;
|
position.indexed_position = new_indexed_value;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
} else if new_native_position < I80F48::ONE && !position.is_in_use() {
|
} else if new_native_position < I80F48::ONE && !position.is_in_use() {
|
||||||
// if there's less than one token deposited, zero the position
|
// if there's less than one token deposited, zero the position
|
||||||
self.dust = cm!(self.dust + new_native_position);
|
self.dust = cm!(self.dust + new_native_position);
|
||||||
self.indexed_total_borrows =
|
self.indexed_total_borrows =
|
||||||
cm!(self.indexed_total_borrows + position.indexed_value);
|
cm!(self.indexed_total_borrows + position.indexed_position);
|
||||||
position.indexed_value = I80F48::ZERO;
|
position.indexed_position = I80F48::ZERO;
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pay back all borrows
|
// pay back all borrows
|
||||||
self.indexed_total_borrows = cm!(self.indexed_total_borrows + position.indexed_value); // position.value is negative
|
self.indexed_total_borrows = cm!(self.indexed_total_borrows + position.indexed_position); // position.value is negative
|
||||||
position.indexed_value = I80F48::ZERO;
|
position.indexed_position = I80F48::ZERO;
|
||||||
// deposit the rest
|
// deposit the rest
|
||||||
native_amount = cm!(native_amount + native_position);
|
native_amount = cm!(native_amount + native_position);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ impl Bank {
|
||||||
// (amount/index + delta)*index >= amount is a better guarantee.
|
// (amount/index + delta)*index >= amount is a better guarantee.
|
||||||
let indexed_change = cm!(native_amount / self.deposit_index + I80F48::DELTA);
|
let indexed_change = cm!(native_amount / self.deposit_index + I80F48::DELTA);
|
||||||
self.indexed_total_deposits = cm!(self.indexed_total_deposits + indexed_change);
|
self.indexed_total_deposits = cm!(self.indexed_total_deposits + indexed_change);
|
||||||
position.indexed_value = cm!(position.indexed_value + indexed_change);
|
position.indexed_position = cm!(position.indexed_position + indexed_change);
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ impl Bank {
|
||||||
/// fractional withdraws can be relevant during liquidation, for example
|
/// fractional withdraws can be relevant during liquidation, for example
|
||||||
pub fn withdraw_without_fee(
|
pub fn withdraw_without_fee(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
self.withdraw_internal(position, native_amount, false)
|
self.withdraw_internal(position, native_amount, false)
|
||||||
|
@ -189,7 +189,7 @@ impl Bank {
|
||||||
/// fractional withdraws can be relevant during liquidation, for example
|
/// fractional withdraws can be relevant during liquidation, for example
|
||||||
pub fn withdraw_with_fee(
|
pub fn withdraw_with_fee(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
self.withdraw_internal(position, native_amount, true)
|
self.withdraw_internal(position, native_amount, true)
|
||||||
|
@ -197,7 +197,7 @@ impl Bank {
|
||||||
|
|
||||||
fn withdraw_internal(
|
fn withdraw_internal(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
mut native_amount: I80F48,
|
mut native_amount: I80F48,
|
||||||
with_loan_origination_fee: bool,
|
with_loan_origination_fee: bool,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
@ -212,21 +212,21 @@ impl Bank {
|
||||||
// zero the account collecting the leftovers in `dust`
|
// zero the account collecting the leftovers in `dust`
|
||||||
self.dust = cm!(self.dust + new_native_position);
|
self.dust = cm!(self.dust + new_native_position);
|
||||||
self.indexed_total_deposits =
|
self.indexed_total_deposits =
|
||||||
cm!(self.indexed_total_deposits - position.indexed_value);
|
cm!(self.indexed_total_deposits - position.indexed_position);
|
||||||
position.indexed_value = I80F48::ZERO;
|
position.indexed_position = I80F48::ZERO;
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
} else {
|
} else {
|
||||||
// withdraw some deposits leaving a positive balance
|
// withdraw some deposits leaving a positive balance
|
||||||
let indexed_change = cm!(native_amount / self.deposit_index);
|
let indexed_change = cm!(native_amount / self.deposit_index);
|
||||||
self.indexed_total_deposits = cm!(self.indexed_total_deposits - indexed_change);
|
self.indexed_total_deposits = cm!(self.indexed_total_deposits - indexed_change);
|
||||||
position.indexed_value = cm!(position.indexed_value - indexed_change);
|
position.indexed_position = cm!(position.indexed_position - indexed_change);
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// withdraw all deposits
|
// withdraw all deposits
|
||||||
self.indexed_total_deposits = cm!(self.indexed_total_deposits - position.indexed_value);
|
self.indexed_total_deposits = cm!(self.indexed_total_deposits - position.indexed_position);
|
||||||
position.indexed_value = I80F48::ZERO;
|
position.indexed_position = I80F48::ZERO;
|
||||||
// borrow the rest
|
// borrow the rest
|
||||||
native_amount = -new_native_position;
|
native_amount = -new_native_position;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ impl Bank {
|
||||||
// add to borrows
|
// add to borrows
|
||||||
let indexed_change = cm!(native_amount / self.borrow_index);
|
let indexed_change = cm!(native_amount / self.borrow_index);
|
||||||
self.indexed_total_borrows = cm!(self.indexed_total_borrows + indexed_change);
|
self.indexed_total_borrows = cm!(self.indexed_total_borrows + indexed_change);
|
||||||
position.indexed_value = cm!(position.indexed_value - indexed_change);
|
position.indexed_position = cm!(position.indexed_position - indexed_change);
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ impl Bank {
|
||||||
// charge only loan origination fee, assuming borrow has already happened
|
// charge only loan origination fee, assuming borrow has already happened
|
||||||
pub fn charge_loan_origination_fee(
|
pub fn charge_loan_origination_fee(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
already_borrowed_native_amount: I80F48,
|
already_borrowed_native_amount: I80F48,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let loan_origination_fee =
|
let loan_origination_fee =
|
||||||
|
@ -255,7 +255,7 @@ impl Bank {
|
||||||
|
|
||||||
let indexed_change = cm!(loan_origination_fee / self.borrow_index);
|
let indexed_change = cm!(loan_origination_fee / self.borrow_index);
|
||||||
self.indexed_total_borrows = cm!(self.indexed_total_borrows + indexed_change);
|
self.indexed_total_borrows = cm!(self.indexed_total_borrows + indexed_change);
|
||||||
position.indexed_value = cm!(position.indexed_value - indexed_change);
|
position.indexed_position = cm!(position.indexed_position - indexed_change);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ impl Bank {
|
||||||
/// Change a position without applying the loan origination fee
|
/// Change a position without applying the loan origination fee
|
||||||
pub fn change_without_fee(
|
pub fn change_without_fee(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
if native_amount >= 0 {
|
if native_amount >= 0 {
|
||||||
|
@ -276,7 +276,7 @@ impl Bank {
|
||||||
/// Change a position, while taking the loan origination fee into account
|
/// Change a position, while taking the loan origination fee into account
|
||||||
pub fn change_with_fee(
|
pub fn change_with_fee(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: &mut TokenAccount,
|
position: &mut TokenPosition,
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
if native_amount >= 0 {
|
if native_amount >= 0 {
|
||||||
|
@ -438,18 +438,18 @@ mod tests {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut account = TokenAccount {
|
let mut account = TokenPosition {
|
||||||
indexed_value: I80F48::ZERO,
|
indexed_position: I80F48::ZERO,
|
||||||
token_index: 0,
|
token_index: 0,
|
||||||
in_use_count: if is_in_use { 1 } else { 0 },
|
in_use_count: if is_in_use { 1 } else { 0 },
|
||||||
reserved: Default::default(),
|
reserved: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
account.indexed_value = indexed(I80F48::from_num(start), &bank);
|
account.indexed_position = indexed(I80F48::from_num(start), &bank);
|
||||||
if start >= 0.0 {
|
if start >= 0.0 {
|
||||||
bank.indexed_total_deposits = account.indexed_value;
|
bank.indexed_total_deposits = account.indexed_position;
|
||||||
} else {
|
} else {
|
||||||
bank.indexed_total_borrows = -account.indexed_value;
|
bank.indexed_total_borrows = -account.indexed_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the rounded start value
|
// get the rounded start value
|
||||||
|
@ -478,14 +478,14 @@ mod tests {
|
||||||
let expected_indexed = indexed(expected_native, &bank);
|
let expected_indexed = indexed(expected_native, &bank);
|
||||||
|
|
||||||
// at most one epsilon error in the resulting indexed value
|
// at most one epsilon error in the resulting indexed value
|
||||||
assert!((account.indexed_value - expected_indexed).abs() <= epsilon);
|
assert!((account.indexed_position - expected_indexed).abs() <= epsilon);
|
||||||
|
|
||||||
if account.indexed_value.is_positive() {
|
if account.indexed_position.is_positive() {
|
||||||
assert_eq!(bank.indexed_total_deposits, account.indexed_value);
|
assert_eq!(bank.indexed_total_deposits, account.indexed_position);
|
||||||
assert_eq!(bank.indexed_total_borrows, I80F48::ZERO);
|
assert_eq!(bank.indexed_total_borrows, I80F48::ZERO);
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(bank.indexed_total_deposits, I80F48::ZERO);
|
assert_eq!(bank.indexed_total_deposits, I80F48::ZERO);
|
||||||
assert_eq!(bank.indexed_total_borrows, -account.indexed_value);
|
assert_eq!(bank.indexed_total_borrows, -account.indexed_position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::state::*;
|
||||||
// we could probably support 1 token (quote currency) + 15 active perp markets at the same time
|
// we could probably support 1 token (quote currency) + 15 active perp markets at the same time
|
||||||
// It's a tradeoff between allowing users to trade on many markets with one account,
|
// It's a tradeoff between allowing users to trade on many markets with one account,
|
||||||
// MangoAccount size and health compute needs.
|
// MangoAccount size and health compute needs.
|
||||||
const MAX_TOKEN_ACCOUNTS: usize = 16;
|
const MAX_TOKEN_POSITIONS: usize = 16;
|
||||||
const MAX_SERUM3_ACCOUNTS: usize = 8;
|
const MAX_SERUM3_ACCOUNTS: usize = 8;
|
||||||
const MAX_PERP_ACCOUNTS: usize = 8;
|
const MAX_PERP_ACCOUNTS: usize = 8;
|
||||||
pub const MAX_PERP_OPEN_ORDERS: usize = 8;
|
pub const MAX_PERP_OPEN_ORDERS: usize = 8;
|
||||||
|
@ -26,14 +26,14 @@ pub const FREE_ORDER_SLOT: PerpMarketIndex = PerpMarketIndex::MAX;
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TokenAccount {
|
pub struct TokenPosition {
|
||||||
// TODO: Why did we have deposits and borrows as two different values
|
// TODO: Why did we have deposits and borrows as two different values
|
||||||
// if only one of them was allowed to be != 0 at a time?
|
// if only one of them was allowed to be != 0 at a time?
|
||||||
// todo: maybe we want to split collateral and lending?
|
// todo: maybe we want to split collateral and lending?
|
||||||
// todo: see https://github.com/blockworks-foundation/mango-v4/issues/1
|
// todo: see https://github.com/blockworks-foundation/mango-v4/issues/1
|
||||||
// todo: how does ftx do this?
|
// todo: how does ftx do this?
|
||||||
/// The deposit_index (if positive) or borrow_index (if negative) scaled position
|
/// The deposit_index (if positive) or borrow_index (if negative) scaled position
|
||||||
pub indexed_value: I80F48,
|
pub indexed_position: I80F48,
|
||||||
|
|
||||||
/// index into Group.tokens
|
/// index into Group.tokens
|
||||||
pub token_index: TokenIndex,
|
pub token_index: TokenIndex,
|
||||||
|
@ -43,10 +43,10 @@ pub struct TokenAccount {
|
||||||
|
|
||||||
pub reserved: [u8; 5],
|
pub reserved: [u8; 5],
|
||||||
}
|
}
|
||||||
const_assert_eq!(size_of::<TokenAccount>(), 24);
|
const_assert_eq!(size_of::<TokenPosition>(), 24);
|
||||||
const_assert_eq!(size_of::<TokenAccount>() % 8, 0);
|
const_assert_eq!(size_of::<TokenPosition>() % 8, 0);
|
||||||
|
|
||||||
impl TokenAccount {
|
impl TokenPosition {
|
||||||
pub fn is_active(&self) -> bool {
|
pub fn is_active(&self) -> bool {
|
||||||
self.token_index != TokenIndex::MAX
|
self.token_index != TokenIndex::MAX
|
||||||
}
|
}
|
||||||
|
@ -56,19 +56,19 @@ impl TokenAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn native(&self, bank: &Bank) -> I80F48 {
|
pub fn native(&self, bank: &Bank) -> I80F48 {
|
||||||
if self.indexed_value.is_positive() {
|
if self.indexed_position.is_positive() {
|
||||||
self.indexed_value * bank.deposit_index
|
self.indexed_position * bank.deposit_index
|
||||||
} else {
|
} else {
|
||||||
self.indexed_value * bank.borrow_index
|
self.indexed_position * bank.borrow_index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&self, bank: &Bank, mint: &Mint) -> I80F48 {
|
pub fn ui(&self, bank: &Bank, mint: &Mint) -> I80F48 {
|
||||||
if self.indexed_value.is_positive() {
|
if self.indexed_position.is_positive() {
|
||||||
(self.indexed_value * bank.deposit_index)
|
(self.indexed_position * bank.deposit_index)
|
||||||
/ I80F48::from_num(10u64.pow(mint.decimals as u32))
|
/ I80F48::from_num(10u64.pow(mint.decimals as u32))
|
||||||
} else {
|
} else {
|
||||||
(self.indexed_value * bank.borrow_index)
|
(self.indexed_position * bank.borrow_index)
|
||||||
/ I80F48::from_num(10u64.pow(mint.decimals as u32))
|
/ I80F48::from_num(10u64.pow(mint.decimals as u32))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,16 +79,16 @@ impl TokenAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct MangoAccountTokens {
|
pub struct MangoAccountTokenPositions {
|
||||||
pub values: [TokenAccount; MAX_TOKEN_ACCOUNTS],
|
pub values: [TokenPosition; MAX_TOKEN_POSITIONS],
|
||||||
}
|
}
|
||||||
const_assert_eq!(
|
const_assert_eq!(
|
||||||
size_of::<MangoAccountTokens>(),
|
size_of::<MangoAccountTokenPositions>(),
|
||||||
MAX_TOKEN_ACCOUNTS * size_of::<TokenAccount>()
|
MAX_TOKEN_POSITIONS * size_of::<TokenPosition>()
|
||||||
);
|
);
|
||||||
const_assert_eq!(size_of::<MangoAccountTokens>() % 8, 0);
|
const_assert_eq!(size_of::<MangoAccountTokenPositions>() % 8, 0);
|
||||||
|
|
||||||
impl std::fmt::Debug for MangoAccountTokens {
|
impl std::fmt::Debug for MangoAccountTokenPositions {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("MangoAccountTokens")
|
f.debug_struct("MangoAccountTokens")
|
||||||
.field(
|
.field(
|
||||||
|
@ -97,52 +97,52 @@ impl std::fmt::Debug for MangoAccountTokens {
|
||||||
.values
|
.values
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|value| value.is_active())
|
.filter(|value| value.is_active())
|
||||||
.collect::<Vec<&TokenAccount>>(),
|
.collect::<Vec<&TokenPosition>>(),
|
||||||
)
|
)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MangoAccountTokens {
|
impl Default for MangoAccountTokenPositions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MangoAccountTokens {
|
impl MangoAccountTokenPositions {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
values: [TokenAccount {
|
values: [TokenPosition {
|
||||||
indexed_value: I80F48::ZERO,
|
indexed_position: I80F48::ZERO,
|
||||||
token_index: TokenIndex::MAX,
|
token_index: TokenIndex::MAX,
|
||||||
in_use_count: 0,
|
in_use_count: 0,
|
||||||
reserved: Default::default(),
|
reserved: Default::default(),
|
||||||
}; MAX_TOKEN_ACCOUNTS],
|
}; MAX_TOKEN_POSITIONS],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, token_index: TokenIndex) -> Result<&TokenAccount> {
|
pub fn get(&self, token_index: TokenIndex) -> Result<&TokenPosition> {
|
||||||
self.values
|
self.values
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.is_active_for_token(token_index))
|
.find(|p| p.is_active_for_token(token_index))
|
||||||
.ok_or_else(|| error!(MangoError::SomeError)) // TODO: not found error
|
.ok_or_else(|| error!(MangoError::SomeError)) // TODO: not found error
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut(&mut self, token_index: TokenIndex) -> Result<&mut TokenAccount> {
|
pub fn get_mut(&mut self, token_index: TokenIndex) -> Result<&mut TokenPosition> {
|
||||||
self.values
|
self.values
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|p| p.is_active_for_token(token_index))
|
.find(|p| p.is_active_for_token(token_index))
|
||||||
.ok_or_else(|| error!(MangoError::SomeError)) // TODO: not found error
|
.ok_or_else(|| error!(MangoError::SomeError)) // TODO: not found error
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_raw(&mut self, raw_token_index: usize) -> &mut TokenAccount {
|
pub fn get_mut_raw(&mut self, raw_token_index: usize) -> &mut TokenPosition {
|
||||||
&mut self.values[raw_token_index]
|
&mut self.values[raw_token_index]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_or_create(
|
pub fn get_mut_or_create(
|
||||||
&mut self,
|
&mut self,
|
||||||
token_index: TokenIndex,
|
token_index: TokenIndex,
|
||||||
) -> Result<(&mut TokenAccount, usize)> {
|
) -> Result<(&mut TokenPosition, usize)> {
|
||||||
// This function looks complex because of lifetimes.
|
// This function looks complex because of lifetimes.
|
||||||
// Maybe there's a smart way to write it with double iter_mut()
|
// Maybe there's a smart way to write it with double iter_mut()
|
||||||
// that doesn't confuse the borrow checker.
|
// that doesn't confuse the borrow checker.
|
||||||
|
@ -153,8 +153,8 @@ impl MangoAccountTokens {
|
||||||
if pos.is_none() {
|
if pos.is_none() {
|
||||||
pos = self.values.iter().position(|p| !p.is_active());
|
pos = self.values.iter().position(|p| !p.is_active());
|
||||||
if let Some(i) = pos {
|
if let Some(i) = pos {
|
||||||
self.values[i] = TokenAccount {
|
self.values[i] = TokenPosition {
|
||||||
indexed_value: I80F48::ZERO,
|
indexed_position: I80F48::ZERO,
|
||||||
token_index,
|
token_index,
|
||||||
in_use_count: 0,
|
in_use_count: 0,
|
||||||
reserved: Default::default(),
|
reserved: Default::default(),
|
||||||
|
@ -173,11 +173,11 @@ impl MangoAccountTokens {
|
||||||
self.values[index].token_index = TokenIndex::MAX;
|
self.values[index].token_index = TokenIndex::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_active(&self) -> impl Iterator<Item = &TokenAccount> {
|
pub fn iter_active(&self) -> impl Iterator<Item = &TokenPosition> {
|
||||||
self.values.iter().filter(|p| p.is_active())
|
self.values.iter().filter(|p| p.is_active())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find(&self, token_index: TokenIndex) -> Option<&TokenAccount> {
|
pub fn find(&self, token_index: TokenIndex) -> Option<&TokenPosition> {
|
||||||
self.values
|
self.values
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.is_active_for_token(token_index))
|
.find(|p| p.is_active_for_token(token_index))
|
||||||
|
@ -186,7 +186,7 @@ impl MangoAccountTokens {
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Serum3Account {
|
pub struct Serum3Orders {
|
||||||
pub open_orders: Pubkey,
|
pub open_orders: Pubkey,
|
||||||
|
|
||||||
// tracks reserved funds in open orders account,
|
// tracks reserved funds in open orders account,
|
||||||
|
@ -206,10 +206,10 @@ pub struct Serum3Account {
|
||||||
|
|
||||||
pub reserved: [u8; 2],
|
pub reserved: [u8; 2],
|
||||||
}
|
}
|
||||||
const_assert_eq!(size_of::<Serum3Account>(), 32 + 8 * 2 + 2 * 3 + 2);
|
const_assert_eq!(size_of::<Serum3Orders>(), 32 + 8 * 2 + 2 * 3 + 2);
|
||||||
const_assert_eq!(size_of::<Serum3Account>() % 8, 0);
|
const_assert_eq!(size_of::<Serum3Orders>() % 8, 0);
|
||||||
|
|
||||||
impl Serum3Account {
|
impl Serum3Orders {
|
||||||
pub fn is_active(&self) -> bool {
|
pub fn is_active(&self) -> bool {
|
||||||
self.market_index != Serum3MarketIndex::MAX
|
self.market_index != Serum3MarketIndex::MAX
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ impl Serum3Account {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Serum3Account {
|
impl Default for Serum3Orders {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
open_orders: Pubkey::default(),
|
open_orders: Pubkey::default(),
|
||||||
|
@ -234,16 +234,16 @@ impl Default for Serum3Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct MangoAccountSerum3 {
|
pub struct MangoAccountSerum3Orders {
|
||||||
pub values: [Serum3Account; MAX_SERUM3_ACCOUNTS],
|
pub values: [Serum3Orders; MAX_SERUM3_ACCOUNTS],
|
||||||
}
|
}
|
||||||
const_assert_eq!(
|
const_assert_eq!(
|
||||||
size_of::<MangoAccountSerum3>(),
|
size_of::<MangoAccountSerum3Orders>(),
|
||||||
MAX_SERUM3_ACCOUNTS * size_of::<Serum3Account>()
|
MAX_SERUM3_ACCOUNTS * size_of::<Serum3Orders>()
|
||||||
);
|
);
|
||||||
const_assert_eq!(size_of::<MangoAccountSerum3>() % 8, 0);
|
const_assert_eq!(size_of::<MangoAccountSerum3Orders>() % 8, 0);
|
||||||
|
|
||||||
impl std::fmt::Debug for MangoAccountSerum3 {
|
impl std::fmt::Debug for MangoAccountSerum3Orders {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("MangoAccountSerum3")
|
f.debug_struct("MangoAccountSerum3")
|
||||||
.field(
|
.field(
|
||||||
|
@ -252,33 +252,33 @@ impl std::fmt::Debug for MangoAccountSerum3 {
|
||||||
.values
|
.values
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|value| value.is_active())
|
.filter(|value| value.is_active())
|
||||||
.collect::<Vec<&Serum3Account>>(),
|
.collect::<Vec<&Serum3Orders>>(),
|
||||||
)
|
)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MangoAccountSerum3 {
|
impl Default for MangoAccountSerum3Orders {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MangoAccountSerum3 {
|
impl MangoAccountSerum3Orders {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
values: [Serum3Account::default(); MAX_SERUM3_ACCOUNTS],
|
values: [Serum3Orders::default(); MAX_SERUM3_ACCOUNTS],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(&mut self, market_index: Serum3MarketIndex) -> Result<&mut Serum3Account> {
|
pub fn create(&mut self, market_index: Serum3MarketIndex) -> Result<&mut Serum3Orders> {
|
||||||
if self.find(market_index).is_some() {
|
if self.find(market_index).is_some() {
|
||||||
return err!(MangoError::SomeError); // exists already
|
return err!(MangoError::SomeError); // exists already
|
||||||
}
|
}
|
||||||
if let Some(v) = self.values.iter_mut().find(|p| !p.is_active()) {
|
if let Some(v) = self.values.iter_mut().find(|p| !p.is_active()) {
|
||||||
*v = Serum3Account {
|
*v = Serum3Orders {
|
||||||
market_index: market_index as Serum3MarketIndex,
|
market_index: market_index as Serum3MarketIndex,
|
||||||
..Serum3Account::default()
|
..Serum3Orders::default()
|
||||||
};
|
};
|
||||||
Ok(v)
|
Ok(v)
|
||||||
} else {
|
} else {
|
||||||
|
@ -298,17 +298,17 @@ impl MangoAccountSerum3 {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_active(&self) -> impl Iterator<Item = &Serum3Account> {
|
pub fn iter_active(&self) -> impl Iterator<Item = &Serum3Orders> {
|
||||||
self.values.iter().filter(|p| p.is_active())
|
self.values.iter().filter(|p| p.is_active())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find(&self, market_index: Serum3MarketIndex) -> Option<&Serum3Account> {
|
pub fn find(&self, market_index: Serum3MarketIndex) -> Option<&Serum3Orders> {
|
||||||
self.values
|
self.values
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.is_active_for_market(market_index))
|
.find(|p| p.is_active_for_market(market_index))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_mut(&mut self, market_index: Serum3MarketIndex) -> Option<&mut Serum3Account> {
|
pub fn find_mut(&mut self, market_index: Serum3MarketIndex) -> Option<&mut Serum3Orders> {
|
||||||
self.values
|
self.values
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|p| p.is_active_for_market(market_index))
|
.find(|p| p.is_active_for_market(market_index))
|
||||||
|
@ -316,7 +316,7 @@ impl MangoAccountSerum3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct PerpAccount {
|
pub struct PerpPositions {
|
||||||
pub market_index: PerpMarketIndex,
|
pub market_index: PerpMarketIndex,
|
||||||
pub reserved: [u8; 6],
|
pub reserved: [u8; 6],
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ pub struct PerpAccount {
|
||||||
pub taker_quote_lots: i64,
|
pub taker_quote_lots: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for PerpAccount {
|
impl std::fmt::Debug for PerpPositions {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("PerpAccount")
|
f.debug_struct("PerpAccount")
|
||||||
.field("market_index", &self.market_index)
|
.field("market_index", &self.market_index)
|
||||||
|
@ -356,10 +356,10 @@ impl std::fmt::Debug for PerpAccount {
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const_assert_eq!(size_of::<PerpAccount>(), 8 + 8 * 5 + 3 * 16);
|
const_assert_eq!(size_of::<PerpPositions>(), 8 + 8 * 5 + 3 * 16);
|
||||||
const_assert_eq!(size_of::<PerpAccount>() % 8, 0);
|
const_assert_eq!(size_of::<PerpPositions>() % 8, 0);
|
||||||
|
|
||||||
impl Default for PerpAccount {
|
impl Default for PerpPositions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
market_index: PerpMarketIndex::MAX,
|
market_index: PerpMarketIndex::MAX,
|
||||||
|
@ -376,7 +376,7 @@ impl Default for PerpAccount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PerpAccount {
|
impl PerpPositions {
|
||||||
/// Add taker trade after it has been matched but before it has been process on EventQueue
|
/// Add taker trade after it has been matched but before it has been process on EventQueue
|
||||||
pub fn add_taker_trade(&mut self, side: Side, base_lots: i64, quote_lots: i64) {
|
pub fn add_taker_trade(&mut self, side: Side, base_lots: i64, quote_lots: i64) {
|
||||||
match side {
|
match side {
|
||||||
|
@ -432,8 +432,8 @@ impl PerpAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zero_copy]
|
#[zero_copy]
|
||||||
pub struct MangoAccountPerps {
|
pub struct MangoAccountPerpPositions {
|
||||||
pub accounts: [PerpAccount; MAX_PERP_ACCOUNTS],
|
pub accounts: [PerpPositions; 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?
|
||||||
pub order_market: [PerpMarketIndex; MAX_PERP_OPEN_ORDERS],
|
pub order_market: [PerpMarketIndex; MAX_PERP_OPEN_ORDERS],
|
||||||
|
@ -442,12 +442,12 @@ pub struct MangoAccountPerps {
|
||||||
pub client_order_id: [u64; MAX_PERP_OPEN_ORDERS],
|
pub client_order_id: [u64; MAX_PERP_OPEN_ORDERS],
|
||||||
}
|
}
|
||||||
const_assert_eq!(
|
const_assert_eq!(
|
||||||
size_of::<MangoAccountPerps>(),
|
size_of::<MangoAccountPerpPositions>(),
|
||||||
MAX_PERP_ACCOUNTS * size_of::<PerpAccount>() + MAX_PERP_OPEN_ORDERS * (2 + 1 + 16 + 8)
|
MAX_PERP_ACCOUNTS * size_of::<PerpPositions>() + MAX_PERP_OPEN_ORDERS * (2 + 1 + 16 + 8)
|
||||||
);
|
);
|
||||||
const_assert_eq!(size_of::<MangoAccountPerps>() % 8, 0);
|
const_assert_eq!(size_of::<MangoAccountPerpPositions>() % 8, 0);
|
||||||
|
|
||||||
impl std::fmt::Debug for MangoAccountPerps {
|
impl std::fmt::Debug for MangoAccountPerpPositions {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("MangoAccountPerps")
|
f.debug_struct("MangoAccountPerps")
|
||||||
.field(
|
.field(
|
||||||
|
@ -456,7 +456,7 @@ impl std::fmt::Debug for MangoAccountPerps {
|
||||||
.accounts
|
.accounts
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|value| value.is_active())
|
.filter(|value| value.is_active())
|
||||||
.collect::<Vec<&PerpAccount>>(),
|
.collect::<Vec<&PerpPositions>>(),
|
||||||
)
|
)
|
||||||
.field(
|
.field(
|
||||||
"order_market",
|
"order_market",
|
||||||
|
@ -496,10 +496,10 @@ impl std::fmt::Debug for MangoAccountPerps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MangoAccountPerps {
|
impl MangoAccountPerpPositions {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
accounts: [PerpAccount::default(); MAX_PERP_ACCOUNTS],
|
accounts: [PerpPositions::default(); MAX_PERP_ACCOUNTS],
|
||||||
order_market: [FREE_ORDER_SLOT; MAX_PERP_OPEN_ORDERS],
|
order_market: [FREE_ORDER_SLOT; MAX_PERP_OPEN_ORDERS],
|
||||||
order_side: [Side::Bid; MAX_PERP_OPEN_ORDERS],
|
order_side: [Side::Bid; MAX_PERP_OPEN_ORDERS],
|
||||||
order_id: [0; MAX_PERP_OPEN_ORDERS],
|
order_id: [0; MAX_PERP_OPEN_ORDERS],
|
||||||
|
@ -510,7 +510,7 @@ impl MangoAccountPerps {
|
||||||
pub fn get_account_mut_or_create(
|
pub fn get_account_mut_or_create(
|
||||||
&mut self,
|
&mut self,
|
||||||
perp_market_index: PerpMarketIndex,
|
perp_market_index: PerpMarketIndex,
|
||||||
) -> Result<(&mut PerpAccount, usize)> {
|
) -> Result<(&mut PerpPositions, usize)> {
|
||||||
let mut pos = self
|
let mut pos = self
|
||||||
.accounts
|
.accounts
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -518,7 +518,7 @@ impl MangoAccountPerps {
|
||||||
if pos.is_none() {
|
if pos.is_none() {
|
||||||
pos = self.accounts.iter().position(|p| !p.is_active());
|
pos = self.accounts.iter().position(|p| !p.is_active());
|
||||||
if let Some(i) = pos {
|
if let Some(i) = pos {
|
||||||
self.accounts[i] = PerpAccount {
|
self.accounts[i] = PerpPositions {
|
||||||
market_index: perp_market_index,
|
market_index: perp_market_index,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
@ -535,11 +535,11 @@ impl MangoAccountPerps {
|
||||||
self.accounts[index].market_index = PerpMarketIndex::MAX;
|
self.accounts[index].market_index = PerpMarketIndex::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_active_accounts(&self) -> impl Iterator<Item = &PerpAccount> {
|
pub fn iter_active_accounts(&self) -> impl Iterator<Item = &PerpPositions> {
|
||||||
self.accounts.iter().filter(|p| p.is_active())
|
self.accounts.iter().filter(|p| p.is_active())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_account(&self, market_index: PerpMarketIndex) -> Option<&PerpAccount> {
|
pub fn find_account(&self, market_index: PerpMarketIndex) -> Option<&PerpPositions> {
|
||||||
self.accounts
|
self.accounts
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.is_active_for_market(market_index))
|
.find(|p| p.is_active_for_market(market_index))
|
||||||
|
@ -682,7 +682,7 @@ impl MangoAccountPerps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MangoAccountPerps {
|
impl Default for MangoAccountPerpPositions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
|
@ -700,13 +700,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 tokens: MangoAccountTokens,
|
pub tokens: MangoAccountTokenPositions,
|
||||||
|
|
||||||
// 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: MangoAccountSerum3,
|
pub serum3: MangoAccountSerum3Orders,
|
||||||
|
|
||||||
pub perps: MangoAccountPerps,
|
pub perps: MangoAccountPerpPositions,
|
||||||
|
|
||||||
/// 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,
|
||||||
|
@ -723,9 +723,9 @@ pub struct MangoAccount {
|
||||||
const_assert_eq!(
|
const_assert_eq!(
|
||||||
size_of::<MangoAccount>(),
|
size_of::<MangoAccount>(),
|
||||||
32 + 3 * 32
|
32 + 3 * 32
|
||||||
+ size_of::<MangoAccountTokens>()
|
+ size_of::<MangoAccountTokenPositions>()
|
||||||
+ size_of::<MangoAccountSerum3>()
|
+ size_of::<MangoAccountSerum3Orders>()
|
||||||
+ size_of::<MangoAccountPerps>()
|
+ size_of::<MangoAccountPerpPositions>()
|
||||||
+ 4
|
+ 4
|
||||||
+ 4
|
+ 4
|
||||||
);
|
);
|
||||||
|
@ -765,9 +765,9 @@ impl Default for MangoAccount {
|
||||||
group: Pubkey::default(),
|
group: Pubkey::default(),
|
||||||
owner: Pubkey::default(),
|
owner: Pubkey::default(),
|
||||||
delegate: Pubkey::default(),
|
delegate: Pubkey::default(),
|
||||||
tokens: MangoAccountTokens::new(),
|
tokens: MangoAccountTokenPositions::new(),
|
||||||
serum3: MangoAccountSerum3::new(),
|
serum3: MangoAccountSerum3Orders::new(),
|
||||||
perps: MangoAccountPerps::new(),
|
perps: MangoAccountPerpPositions::new(),
|
||||||
being_liquidated: 0,
|
being_liquidated: 0,
|
||||||
is_bankrupt: 0,
|
is_bankrupt: 0,
|
||||||
account_num: 0,
|
account_num: 0,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
error::MangoError,
|
error::MangoError,
|
||||||
state::{
|
state::{
|
||||||
orderbook::{bookside::BookSide, nodes::LeafNode},
|
orderbook::{bookside::BookSide, nodes::LeafNode},
|
||||||
EventQueue, MangoAccount, MangoAccountPerps, PerpMarket, FREE_ORDER_SLOT,
|
EventQueue, MangoAccount, MangoAccountPerpPositions, PerpMarket, FREE_ORDER_SLOT,
|
||||||
MAX_PERP_OPEN_ORDERS,
|
MAX_PERP_OPEN_ORDERS,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -155,7 +155,7 @@ impl<'a> Book<'a> {
|
||||||
perp_market: &mut PerpMarket,
|
perp_market: &mut PerpMarket,
|
||||||
event_queue: &mut EventQueue,
|
event_queue: &mut EventQueue,
|
||||||
oracle_price: I80F48,
|
oracle_price: I80F48,
|
||||||
mango_account_perps: &mut MangoAccountPerps,
|
mango_account_perps: &mut MangoAccountPerpPositions,
|
||||||
mango_account_pk: &Pubkey,
|
mango_account_pk: &Pubkey,
|
||||||
price_lots: i64,
|
price_lots: i64,
|
||||||
max_base_lots: i64,
|
max_base_lots: i64,
|
||||||
|
@ -437,7 +437,7 @@ impl<'a> Book<'a> {
|
||||||
/// both the maker and taker fees.
|
/// both the maker and taker fees.
|
||||||
fn apply_fees(
|
fn apply_fees(
|
||||||
market: &mut PerpMarket,
|
market: &mut PerpMarket,
|
||||||
mango_account_perps: &mut MangoAccountPerps,
|
mango_account_perps: &mut MangoAccountPerpPositions,
|
||||||
total_quote_taken: i64,
|
total_quote_taken: i64,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let taker_quote_native = I80F48::from_num(
|
let taker_quote_native = I80F48::from_num(
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub mod queue;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::state::{MangoAccountPerps, PerpMarket, FREE_ORDER_SLOT};
|
use crate::state::{MangoAccountPerpPositions, PerpMarket, FREE_ORDER_SLOT};
|
||||||
use bytemuck::Zeroable;
|
use bytemuck::Zeroable;
|
||||||
use fixed::types::I80F48;
|
use fixed::types::I80F48;
|
||||||
use solana_program::pubkey::Pubkey;
|
use solana_program::pubkey::Pubkey;
|
||||||
|
@ -99,7 +99,7 @@ mod tests {
|
||||||
|
|
||||||
let mut new_order =
|
let mut new_order =
|
||||||
|book: &mut Book, event_queue: &mut EventQueue, side, price, now_ts| -> i128 {
|
|book: &mut Book, event_queue: &mut EventQueue, side, price, now_ts| -> i128 {
|
||||||
let mut account_perps = MangoAccountPerps::new();
|
let mut account_perps = MangoAccountPerpPositions::new();
|
||||||
|
|
||||||
let quantity = 1;
|
let quantity = 1;
|
||||||
let tif = 100;
|
let tif = 100;
|
||||||
|
@ -193,8 +193,8 @@ mod tests {
|
||||||
market.maker_fee = I80F48::from_num(-0.001f64);
|
market.maker_fee = I80F48::from_num(-0.001f64);
|
||||||
market.taker_fee = I80F48::from_num(0.01f64);
|
market.taker_fee = I80F48::from_num(0.01f64);
|
||||||
|
|
||||||
let mut maker = MangoAccountPerps::new();
|
let mut maker = MangoAccountPerpPositions::new();
|
||||||
let mut taker = MangoAccountPerps::new();
|
let mut taker = MangoAccountPerpPositions::new();
|
||||||
let maker_pk = Pubkey::new_unique();
|
let maker_pk = Pubkey::new_unique();
|
||||||
let taker_pk = Pubkey::new_unique();
|
let taker_pk = Pubkey::new_unique();
|
||||||
let now_ts = 1000000;
|
let now_ts = 1000000;
|
||||||
|
|
Loading…
Reference in New Issue