bad code; WILL THROW STACK FRAME ERROR IN PROD
This commit is contained in:
parent
43e5e83f13
commit
d4fe5c879e
|
@ -20,7 +20,8 @@ cargo build-bpf --features devnet --bpf-out-dir target/devnet
|
||||||
# this will give a separate program id for devnet
|
# this will give a separate program id for devnet
|
||||||
#solana-keygen new --outfile target/devnet/mango-dev.json
|
#solana-keygen new --outfile target/devnet/mango-dev.json
|
||||||
#MANGO_PROGRAM_ID="$(solana program deploy target/devnet/mango.so --program-id target/devnet/mango-dev.json | jq .programId -r)"
|
#MANGO_PROGRAM_ID="$(solana program deploy target/devnet/mango.so --program-id target/devnet/mango-dev.json | jq .programId -r)"
|
||||||
MANGO_PROGRAM_ID="$(solana program deploy target/devnet/mango.so --program-id $MANGO_PROGRAM_ID --keypair $KEYPAIR --output json-compact | jq .programId -r)"
|
#MANGO_PROGRAM_ID="$(solana program deploy target/devnet/mango.so --program-id $MANGO_PROGRAM_ID --keypair $KEYPAIR --output json-compact | jq .programId -r)"
|
||||||
|
solana program deploy target/devnet/mango.so --program-id $MANGO_PROGRAM_ID --keypair $KEYPAIR --output json-compact
|
||||||
popd
|
popd
|
||||||
cd cli
|
cd cli
|
||||||
|
|
||||||
|
|
|
@ -1246,11 +1246,14 @@ impl Processor {
|
||||||
check_open_orders(&open_orders_accs[i], &mango_group.signer_key)?;
|
check_open_orders(&open_orders_accs[i], &mango_group.signer_key)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sol_log_compute_units();
|
||||||
let clock = Clock::from_account_info(clock_acc)?;
|
let clock = Clock::from_account_info(clock_acc)?;
|
||||||
mango_group.update_indexes(&clock)?; // TODO consider removing for compute limit space
|
mango_group.update_indexes(&clock)?; // TODO consider removing for compute limit space
|
||||||
|
sol_log_compute_units();
|
||||||
|
|
||||||
let prices = get_prices(&mango_group, oracle_accs)?;
|
let prices = get_prices(&mango_group, oracle_accs)?;
|
||||||
let start_assets = liqee_margin_account.get_total_assets(&mango_group, open_orders_accs)?;
|
let start_assets = liqee_margin_account.get_assets(&mango_group, open_orders_accs)?;
|
||||||
let start_liabs = liqee_margin_account.get_total_liabs(&mango_group)?;
|
let start_liabs = liqee_margin_account.get_liabs(&mango_group)?;
|
||||||
let coll_ratio = liqee_margin_account.coll_ratio_from_assets_liabs(
|
let coll_ratio = liqee_margin_account.coll_ratio_from_assets_liabs(
|
||||||
&prices, &start_assets, &start_liabs)?;
|
&prices, &start_assets, &start_liabs)?;
|
||||||
// let coll_ratio = liqee_margin_account.get_collateral_ratio(
|
// let coll_ratio = liqee_margin_account.get_collateral_ratio(
|
||||||
|
@ -1300,12 +1303,11 @@ impl Processor {
|
||||||
&[&signers_seeds], out_quantity)?;
|
&[&signers_seeds], out_quantity)?;
|
||||||
|
|
||||||
// Check if account valid now
|
// Check if account valid now
|
||||||
sol_log_compute_units();
|
let end_assets = liqee_margin_account.get_assets(&mango_group, open_orders_accs)?;
|
||||||
let end_assets = liqee_margin_account.get_total_assets(&mango_group, open_orders_accs)?;
|
let end_liabs = liqee_margin_account.get_liabs(&mango_group)?;
|
||||||
let end_liabs = liqee_margin_account.get_total_liabs(&mango_group)?;
|
|
||||||
let coll_ratio = liqee_margin_account.coll_ratio_from_assets_liabs(
|
let coll_ratio = liqee_margin_account.coll_ratio_from_assets_liabs(
|
||||||
&prices, &end_assets, &end_liabs)?;
|
&prices, &end_assets, &end_liabs)?;
|
||||||
let mut total_deposits = [0u64; NUM_TOKENS];
|
let mut total_deposits = [ZERO_U64F64; NUM_TOKENS];
|
||||||
|
|
||||||
let mut socialized_losses = false;
|
let mut socialized_losses = false;
|
||||||
if coll_ratio >= mango_group.init_coll_ratio {
|
if coll_ratio >= mango_group.init_coll_ratio {
|
||||||
|
@ -1313,17 +1315,18 @@ impl Processor {
|
||||||
liqee_margin_account.being_liquidated = false;
|
liqee_margin_account.being_liquidated = false;
|
||||||
} else {
|
} else {
|
||||||
// if all asset vals is dust (less than 1 cent?) socialize loss on lenders
|
// if all asset vals is dust (less than 1 cent?) socialize loss on lenders
|
||||||
let assets_val = liqee_margin_account.get_assets_val(&mango_group, &prices, open_orders_accs)?;
|
let assets_val = dot_product(&end_assets, &prices);
|
||||||
|
|
||||||
if assets_val < DUST_THRESHOLD {
|
if assets_val < DUST_THRESHOLD {
|
||||||
for i in 0..NUM_TOKENS {
|
for i in 0..NUM_TOKENS {
|
||||||
let native_borrow: U64F64 = liqee_margin_account.borrows[i] * mango_group.indexes[i].borrow;
|
let native_borrow: U64F64 = liqee_margin_account.borrows[i] * mango_group.indexes[i].borrow;
|
||||||
let total_deposits_native: U64F64 = mango_group.total_deposits[i] * mango_group.indexes[i].deposit;
|
let total_deposits_native: U64F64 = mango_group.total_deposits[i] * mango_group.indexes[i].deposit;
|
||||||
|
|
||||||
total_deposits[i] = total_deposits_native.to_num();
|
total_deposits[i] = total_deposits_native;
|
||||||
|
|
||||||
if native_borrow > 0 {
|
if native_borrow > 0 {
|
||||||
socialized_losses = true;
|
socialized_losses = true;
|
||||||
|
|
||||||
socialize_loss(
|
socialize_loss(
|
||||||
&mut mango_group,
|
&mut mango_group,
|
||||||
&mut liqee_margin_account,
|
&mut liqee_margin_account,
|
||||||
|
@ -1336,19 +1339,8 @@ impl Processor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut prices_f64 = [0_f64; NUM_TOKENS];
|
|
||||||
for i in 0..NUM_TOKENS {
|
|
||||||
prices_f64[i] = prices[i].to_num::<f64>();
|
|
||||||
}
|
|
||||||
// Note total_deposits is only logged with reasonable values if assets_val < DUST_THRESHOLD
|
// Note total_deposits is only logged with reasonable values if assets_val < DUST_THRESHOLD
|
||||||
msg!("liquidation details: {{ \
|
log_liquidation_details(&start_assets, &start_liabs, &end_assets, &end_liabs, &prices, socialized_losses, &total_deposits);
|
||||||
\"start\": {{ \"assets\": {:?}, \"liabs\": {:?} }}, \
|
|
||||||
\"end\": {{ \"assets\": {:?}, \"liabs\": {:?} }}, \
|
|
||||||
\"prices\": {:?}, \
|
|
||||||
\"socialized_losses\": {}, \
|
|
||||||
\"total_deposits\": {:?} \
|
|
||||||
}}", start_assets, start_liabs, end_assets, end_liabs, prices_f64, socialized_losses, total_deposits);
|
|
||||||
sol_log_compute_units();
|
|
||||||
|
|
||||||
// TODO do I need to check total deposits and total borrows?
|
// TODO do I need to check total deposits and total borrows?
|
||||||
// TODO log deposit indexes before and after liquidation as a way to measure socialize of losses
|
// TODO log deposit indexes before and after liquidation as a way to measure socialize of losses
|
||||||
|
@ -1471,7 +1463,50 @@ impl Processor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn dot_product(a: &[U64F64; NUM_TOKENS], b: &[U64F64; NUM_TOKENS]) -> U64F64 {
|
||||||
|
let mut val = ZERO_U64F64;
|
||||||
|
for i in 0..NUM_TOKENS {
|
||||||
|
val = a[i].checked_mul(b[i]).unwrap().checked_add(val).unwrap()
|
||||||
|
}
|
||||||
|
val
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn log_liquidation_details(
|
||||||
|
start_assets: &[U64F64; NUM_TOKENS],
|
||||||
|
start_liabs: &[U64F64; NUM_TOKENS],
|
||||||
|
end_assets: &[U64F64; NUM_TOKENS],
|
||||||
|
end_liabs: &[U64F64; NUM_TOKENS],
|
||||||
|
prices: &[U64F64; NUM_TOKENS],
|
||||||
|
socialized_losses: bool,
|
||||||
|
total_deposits: &[U64F64; NUM_TOKENS]
|
||||||
|
) {
|
||||||
|
let mut prices_f64 = [0_f64; NUM_TOKENS];
|
||||||
|
let mut start_assets_u64 = [0u64; NUM_TOKENS];
|
||||||
|
let mut start_liabs_u64 = [0u64; NUM_TOKENS];
|
||||||
|
let mut end_assets_u64 = [0u64; NUM_TOKENS];
|
||||||
|
let mut end_liabs_u64 = [0u64; NUM_TOKENS];
|
||||||
|
let mut total_deposits_u64 = [0u64; NUM_TOKENS];
|
||||||
|
for i in 0..NUM_TOKENS {
|
||||||
|
prices_f64[i] = prices[i].to_num::<f64>();
|
||||||
|
start_assets_u64[i] = start_assets[i].to_num();
|
||||||
|
start_liabs_u64[i] = start_liabs[i].to_num();
|
||||||
|
end_assets_u64[i] = end_assets[i].to_num();
|
||||||
|
end_liabs_u64[i] = end_liabs[i].to_num();
|
||||||
|
total_deposits_u64[i] = total_deposits[i].to_num();
|
||||||
|
}
|
||||||
|
// Note total_deposits is only logged with reasonable values if assets_val < DUST_THRESHOLD
|
||||||
|
msg!("liquidation details: {{ \
|
||||||
|
\"start\": {{ \"assets\": {:?}, \"liabs\": {:?} }}, \
|
||||||
|
\"end\": {{ \"assets\": {:?}, \"liabs\": {:?} }}, \
|
||||||
|
\"prices\": {:?}, \
|
||||||
|
\"socialized_losses\": {}, \
|
||||||
|
\"total_deposits\": {:?} \
|
||||||
|
}}", start_assets_u64, start_liabs_u64, end_assets_u64, end_liabs_u64, prices_f64, socialized_losses, total_deposits_u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn settle_borrow_unchecked(
|
fn settle_borrow_unchecked(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1499,6 +1534,7 @@ fn settle_borrow_unchecked(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn settle_borrow_full_unchecked(
|
fn settle_borrow_full_unchecked(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1523,6 +1559,7 @@ fn settle_borrow_full_unchecked(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn socialize_loss(
|
fn socialize_loss(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1546,6 +1583,7 @@ fn socialize_loss(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn checked_sub_deposit(
|
fn checked_sub_deposit(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1556,6 +1594,7 @@ fn checked_sub_deposit(
|
||||||
mango_group.checked_sub_deposit(token_index, quantity)
|
mango_group.checked_sub_deposit(token_index, quantity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn checked_sub_borrow(
|
fn checked_sub_borrow(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1576,6 +1615,7 @@ fn checked_sub_borrow(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn checked_add_deposit(
|
fn checked_add_deposit(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1586,6 +1626,7 @@ fn checked_add_deposit(
|
||||||
mango_group.checked_add_deposit(token_index, quantity)
|
mango_group.checked_add_deposit(token_index, quantity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn checked_add_borrow(
|
fn checked_add_borrow(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
@ -1602,6 +1643,7 @@ fn checked_add_borrow(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_prices(
|
pub fn get_prices(
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
oracle_accs: &[AccountInfo]
|
oracle_accs: &[AccountInfo]
|
||||||
|
@ -1630,6 +1672,7 @@ pub fn get_prices(
|
||||||
Ok(prices)
|
Ok(prices)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn invoke_settle_funds<'a>(
|
fn invoke_settle_funds<'a>(
|
||||||
dex_prog_acc: &AccountInfo<'a>,
|
dex_prog_acc: &AccountInfo<'a>,
|
||||||
spot_market_acc: &AccountInfo<'a>,
|
spot_market_acc: &AccountInfo<'a>,
|
||||||
|
@ -1675,6 +1718,7 @@ fn invoke_settle_funds<'a>(
|
||||||
solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
|
solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn invoke_cancel_order<'a>(
|
fn invoke_cancel_order<'a>(
|
||||||
dex_prog_acc: &AccountInfo<'a>,
|
dex_prog_acc: &AccountInfo<'a>,
|
||||||
spot_market_acc: &AccountInfo<'a>,
|
spot_market_acc: &AccountInfo<'a>,
|
||||||
|
@ -1712,6 +1756,7 @@ fn invoke_cancel_order<'a>(
|
||||||
solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
|
solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn invoke_cancel_orders<'a>(
|
fn invoke_cancel_orders<'a>(
|
||||||
open_orders_acc: &AccountInfo<'a>,
|
open_orders_acc: &AccountInfo<'a>,
|
||||||
dex_prog_acc: &AccountInfo<'a>,
|
dex_prog_acc: &AccountInfo<'a>,
|
||||||
|
@ -1798,6 +1843,7 @@ fn invoke_cancel_orders<'a>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn invoke_transfer<'a>(
|
fn invoke_transfer<'a>(
|
||||||
token_prog_acc: &AccountInfo<'a>,
|
token_prog_acc: &AccountInfo<'a>,
|
||||||
source_acc: &AccountInfo<'a>,
|
source_acc: &AccountInfo<'a>,
|
||||||
|
@ -1825,6 +1871,7 @@ fn invoke_transfer<'a>(
|
||||||
solana_program::program::invoke_signed(&transfer_instruction, &accs, signers_seeds)
|
solana_program::program::invoke_signed(&transfer_instruction, &accs, signers_seeds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn get_in_out_quantities(
|
fn get_in_out_quantities(
|
||||||
mango_group: &mut MangoGroup,
|
mango_group: &mut MangoGroup,
|
||||||
margin_account: &mut MarginAccount,
|
margin_account: &mut MarginAccount,
|
||||||
|
|
|
@ -10,7 +10,6 @@ use solana_program::account_info::AccountInfo;
|
||||||
use solana_program::clock::Clock;
|
use solana_program::clock::Clock;
|
||||||
use solana_program::program_error::ProgramError;
|
use solana_program::program_error::ProgramError;
|
||||||
use solana_program::pubkey::Pubkey;
|
use solana_program::pubkey::Pubkey;
|
||||||
use solana_program::msg;
|
|
||||||
|
|
||||||
use fixed_macro::types::U64F64;
|
use fixed_macro::types::U64F64;
|
||||||
|
|
||||||
|
@ -31,7 +30,7 @@ const MAX_R: U64F64 = U64F64!(9.5129375951293759512937e-08); // max 300% APY ->
|
||||||
pub const ONE_U64F64: U64F64 = U64F64!(1);
|
pub const ONE_U64F64: U64F64 = U64F64!(1);
|
||||||
pub const ZERO_U64F64: U64F64 = U64F64!(0);
|
pub const ZERO_U64F64: U64F64 = U64F64!(0);
|
||||||
pub const PARTIAL_LIQ_INCENTIVE: U64F64 = U64F64!(1.05);
|
pub const PARTIAL_LIQ_INCENTIVE: U64F64 = U64F64!(1.05);
|
||||||
pub const DUST_THRESHOLD: U64F64 = U64F64!(0.01); // TODO make this part of MangoGroup state
|
pub const DUST_THRESHOLD: U64F64 = U64F64!(100000); // TODO make this part of MangoGroup state
|
||||||
pub const EPSILON: U64F64 = U64F64!(1.0e-17);
|
pub const EPSILON: U64F64 = U64F64!(1.0e-17);
|
||||||
|
|
||||||
macro_rules! check_default {
|
macro_rules! check_default {
|
||||||
|
@ -173,6 +172,7 @@ impl MangoGroup {
|
||||||
self.vaults.iter().position(|pk| pk == vault)
|
self.vaults.iter().position(|pk| pk == vault)
|
||||||
}
|
}
|
||||||
/// interest is in units per second (e.g. 0.01 => 1% interest per second)
|
/// interest is in units per second (e.g. 0.01 => 1% interest per second)
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_interest_rate(&self, token_index: usize) -> U64F64 {
|
pub fn get_interest_rate(&self, token_index: usize) -> U64F64 {
|
||||||
let index: &MangoIndex = &self.indexes[token_index];
|
let index: &MangoIndex = &self.indexes[token_index];
|
||||||
let native_deposits = index.deposit.checked_mul(self.total_deposits[token_index]).unwrap();
|
let native_deposits = index.deposit.checked_mul(self.total_deposits[token_index]).unwrap();
|
||||||
|
@ -191,6 +191,7 @@ impl MangoGroup {
|
||||||
slope * utilization
|
slope * utilization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn update_indexes(&mut self, clock: &Clock) -> MangoResult<()> {
|
pub fn update_indexes(&mut self, clock: &Clock) -> MangoResult<()> {
|
||||||
// TODO verify what happens if total_deposits < total_borrows
|
// TODO verify what happens if total_deposits < total_borrows
|
||||||
// TODO verify what happens if total_deposits == 0 && total_borrows > 0
|
// TODO verify what happens if total_deposits == 0 && total_borrows > 0
|
||||||
|
@ -228,30 +229,37 @@ impl MangoGroup {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn has_valid_deposits_borrows(&self, token_i: usize) -> bool {
|
pub fn has_valid_deposits_borrows(&self, token_i: usize) -> bool {
|
||||||
self.get_total_native_deposit(token_i) >= self.get_total_native_borrow(token_i)
|
self.get_total_native_deposit(token_i) >= self.get_total_native_borrow(token_i)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_total_native_borrow(&self, token_i: usize) -> u64 {
|
pub fn get_total_native_borrow(&self, token_i: usize) -> u64 {
|
||||||
let native: U64F64 = self.total_borrows[token_i] * self.indexes[token_i].borrow;
|
let native: U64F64 = self.total_borrows[token_i] * self.indexes[token_i].borrow;
|
||||||
native.checked_ceil().unwrap().to_num() // rounds toward +inf
|
native.checked_ceil().unwrap().to_num() // rounds toward +inf
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_total_native_deposit(&self, token_i: usize) -> u64 {
|
pub fn get_total_native_deposit(&self, token_i: usize) -> u64 {
|
||||||
let native: U64F64 = self.total_deposits[token_i] * self.indexes[token_i].deposit;
|
let native: U64F64 = self.total_deposits[token_i] * self.indexes[token_i].deposit;
|
||||||
native.checked_floor().unwrap().to_num() // rounds toward -inf
|
native.checked_floor().unwrap().to_num() // rounds toward -inf
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_market_index(&self, spot_market_pk: &Pubkey) -> Option<usize> {
|
pub fn get_market_index(&self, spot_market_pk: &Pubkey) -> Option<usize> {
|
||||||
self.spot_markets.iter().position(|market| market == spot_market_pk)
|
self.spot_markets.iter().position(|market| market == spot_market_pk)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_add_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_add_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.total_borrows[token_i] = self.total_borrows[token_i].checked_add(v).ok_or(throw!())?)
|
Ok(self.total_borrows[token_i] = self.total_borrows[token_i].checked_add(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_sub_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_sub_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.total_borrows[token_i] = self.total_borrows[token_i].checked_sub(v).ok_or(throw!())?)
|
Ok(self.total_borrows[token_i] = self.total_borrows[token_i].checked_sub(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_add_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_add_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.total_deposits[token_i] = self.total_deposits[token_i].checked_add(v).ok_or(throw!())?)
|
Ok(self.total_deposits[token_i] = self.total_deposits[token_i].checked_add(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_sub_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_sub_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.total_deposits[token_i] = self.total_deposits[token_i].checked_sub(v).ok_or(throw!())?)
|
Ok(self.total_deposits[token_i] = self.total_deposits[token_i].checked_sub(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
@ -328,6 +336,7 @@ impl MarginAccount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_collateral_ratio(
|
pub fn get_collateral_ratio(
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
|
@ -344,17 +353,18 @@ impl MarginAccount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn coll_ratio_from_assets_liabs(
|
pub fn coll_ratio_from_assets_liabs(
|
||||||
&self,
|
&self,
|
||||||
prices: &[U64F64; NUM_TOKENS],
|
prices: &[U64F64; NUM_TOKENS],
|
||||||
assets: &[u64; NUM_TOKENS],
|
assets: &[U64F64; NUM_TOKENS],
|
||||||
liabs: &[u64; NUM_TOKENS]
|
liabs: &[U64F64; NUM_TOKENS]
|
||||||
) -> MangoResult<U64F64> {
|
) -> MangoResult<U64F64> {
|
||||||
let mut assets_val: U64F64 = ZERO_U64F64;
|
let mut assets_val: U64F64 = ZERO_U64F64;
|
||||||
let mut liabs_val: U64F64 = ZERO_U64F64;
|
let mut liabs_val: U64F64 = ZERO_U64F64;
|
||||||
for i in 0..NUM_TOKENS {
|
for i in 0..NUM_TOKENS {
|
||||||
liabs_val += U64F64::from_num(liabs[i]).checked_mul(prices[i]).unwrap();
|
liabs_val = liabs[i].checked_mul(prices[i]).unwrap().checked_add(liabs_val).unwrap();
|
||||||
assets_val += U64F64::from_num(assets[i]).checked_mul(prices[i]).unwrap();
|
assets_val = assets[i].checked_mul(prices[i]).unwrap().checked_add(assets_val).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if liabs_val == ZERO_U64F64 {
|
if liabs_val == ZERO_U64F64 {
|
||||||
|
@ -363,71 +373,48 @@ impl MarginAccount {
|
||||||
Ok(assets_val.checked_div(liabs_val).unwrap())
|
Ok(assets_val.checked_div(liabs_val).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn logged_get_coll_ratio(
|
|
||||||
&self,
|
|
||||||
mango_group: &MangoGroup,
|
|
||||||
prices: &[U64F64; NUM_TOKENS],
|
|
||||||
open_orders_accs: &[AccountInfo; NUM_MARKETS]
|
|
||||||
) -> MangoResult<U64F64> {
|
|
||||||
let assets = self.get_total_assets(&mango_group, open_orders_accs)?;
|
|
||||||
let liabs = self.get_total_liabs(&mango_group)?;
|
|
||||||
|
|
||||||
let mut assets_val: U64F64 = ZERO_U64F64;
|
#[inline(always)]
|
||||||
let mut liabs_val: U64F64 = ZERO_U64F64;
|
pub fn get_assets(
|
||||||
for i in 0..NUM_TOKENS {
|
|
||||||
liabs_val += U64F64::from_num(liabs[i]).checked_mul(prices[i]).unwrap();
|
|
||||||
assets_val += U64F64::from_num(assets[i]).checked_mul(prices[i]).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let coll_ratio = if liabs_val == ZERO_U64F64 {
|
|
||||||
U64F64::MAX
|
|
||||||
} else {
|
|
||||||
assets_val.checked_div(liabs_val).unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Too expensive to call msg! with an argument of type U64F64 - convert to f64 first
|
|
||||||
let mut prices_f64 = [0_f64; NUM_TOKENS];
|
|
||||||
for i in 0..NUM_TOKENS {
|
|
||||||
prices_f64[i] = prices[i].to_num::<f64>();
|
|
||||||
}
|
|
||||||
msg!("account details: {{ \"assets\": {:?}, \"liabs\": {:?}, \"prices\": {:?}, \"coll_ratio\": {}, \"unused\": {} }}", assets, liabs, prices_f64, coll_ratio.to_num::<f64>(), 0);
|
|
||||||
Ok(coll_ratio)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_total_assets(
|
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
open_orders_accs: &[AccountInfo; NUM_MARKETS]
|
open_orders_accs: &[AccountInfo; NUM_MARKETS]
|
||||||
) -> MangoResult<[u64; NUM_TOKENS]> {
|
) -> MangoResult<[U64F64; NUM_TOKENS]> {
|
||||||
let mut assets = [0u64; NUM_TOKENS];
|
let mut assets = [ZERO_U64F64; NUM_TOKENS];
|
||||||
|
|
||||||
for i in 0..NUM_TOKENS {
|
for i in 0..NUM_TOKENS {
|
||||||
assets[i] = self.get_native_deposit(&mango_group.indexes[i], i)
|
assets[i] = mango_group.indexes[i].deposit.checked_mul(self.deposits[i]).unwrap()
|
||||||
.checked_add(assets[i]).unwrap();
|
.checked_add(assets[i]).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..NUM_MARKETS {
|
for i in 0..NUM_MARKETS {
|
||||||
if *open_orders_accs[i].key == Pubkey::default() {
|
if *open_orders_accs[i].key == Pubkey::default() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let open_orders = load_open_orders(&open_orders_accs[i])?;
|
let open_orders = load_open_orders(&open_orders_accs[i])?;
|
||||||
|
|
||||||
assets[i] = open_orders.native_coin_total.checked_add(assets[i]).unwrap();
|
assets[i] = U64F64::from_num(open_orders.native_coin_total).checked_add(assets[i]).unwrap();
|
||||||
assets[NUM_TOKENS-1] = open_orders.native_pc_total.checked_add(assets[NUM_TOKENS-1]).unwrap();
|
assets[NUM_TOKENS-1] = U64F64::from_num(open_orders.native_pc_total).checked_add(assets[NUM_TOKENS-1]).unwrap();
|
||||||
}
|
}
|
||||||
Ok(assets)
|
Ok(assets)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_total_liabs(
|
#[inline(always)]
|
||||||
|
pub fn get_liabs(
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup
|
mango_group: &MangoGroup,
|
||||||
) -> MangoResult<[u64; NUM_TOKENS]> {
|
) -> MangoResult<[U64F64; NUM_TOKENS]> {
|
||||||
let mut liabs = [0u64; NUM_TOKENS];
|
let mut liabs = [ZERO_U64F64; NUM_TOKENS];
|
||||||
for i in 0.. NUM_TOKENS {
|
|
||||||
liabs[i] = self.get_native_borrow(&mango_group.indexes[i], i);
|
for i in 0..NUM_TOKENS {
|
||||||
|
liabs[i] = mango_group.indexes[i].borrow.checked_mul(self.borrows[i]).unwrap()
|
||||||
|
.checked_add(liabs[i]).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(liabs)
|
Ok(liabs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_assets_val(
|
pub fn get_assets_val(
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
|
@ -448,7 +435,6 @@ impl MarginAccount {
|
||||||
.checked_mul(prices[i]).unwrap()
|
.checked_mul(prices[i]).unwrap()
|
||||||
.checked_add(U64F64::from_num(open_orders.native_pc_total)).unwrap()
|
.checked_add(U64F64::from_num(open_orders.native_pc_total)).unwrap()
|
||||||
.checked_add(assets).unwrap();
|
.checked_add(assets).unwrap();
|
||||||
|
|
||||||
}
|
}
|
||||||
for i in 0..NUM_TOKENS { // add up the value in margin account deposits and positions
|
for i in 0..NUM_TOKENS { // add up the value in margin account deposits and positions
|
||||||
let index: &MangoIndex = &mango_group.indexes[i];
|
let index: &MangoIndex = &mango_group.indexes[i];
|
||||||
|
@ -460,6 +446,8 @@ impl MarginAccount {
|
||||||
Ok(assets)
|
Ok(assets)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_liabs_val(
|
pub fn get_liabs_val(
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
|
@ -474,6 +462,7 @@ impl MarginAccount {
|
||||||
Ok(liabs)
|
Ok(liabs)
|
||||||
}
|
}
|
||||||
/// Return amount of quote currency to deposit to get account above init_coll_ratio
|
/// Return amount of quote currency to deposit to get account above init_coll_ratio
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_collateral_deficit(
|
pub fn get_collateral_deficit(
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
|
@ -490,6 +479,7 @@ impl MarginAccount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_partial_liq_deficit(
|
pub fn get_partial_liq_deficit(
|
||||||
&self,
|
&self,
|
||||||
mango_group: &MangoGroup,
|
mango_group: &MangoGroup,
|
||||||
|
@ -505,23 +495,28 @@ impl MarginAccount {
|
||||||
// TODO make this checked
|
// TODO make this checked
|
||||||
Ok((liabs * mango_group.init_coll_ratio - assets) / (mango_group.init_coll_ratio - PARTIAL_LIQ_INCENTIVE))
|
Ok((liabs * mango_group.init_coll_ratio - assets) / (mango_group.init_coll_ratio - PARTIAL_LIQ_INCENTIVE))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_native_borrow(&self, index: &MangoIndex, token_i: usize) -> u64 {
|
pub fn get_native_borrow(&self, index: &MangoIndex, token_i: usize) -> u64 {
|
||||||
(self.borrows[token_i] * index.borrow).to_num()
|
(self.borrows[token_i] * index.borrow).to_num()
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_native_deposit(&self, index: &MangoIndex, token_i: usize) -> u64 {
|
pub fn get_native_deposit(&self, index: &MangoIndex, token_i: usize) -> u64 {
|
||||||
(self.deposits[token_i] * index.deposit).to_num()
|
(self.deposits[token_i] * index.deposit).to_num()
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_add_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_add_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.borrows[token_i] = self.borrows[token_i].checked_add(v).ok_or(throw!())?)
|
Ok(self.borrows[token_i] = self.borrows[token_i].checked_add(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_sub_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_sub_borrow(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.borrows[token_i] = self.borrows[token_i].checked_sub(v).ok_or(throw!())?)
|
Ok(self.borrows[token_i] = self.borrows[token_i].checked_sub(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_add_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_add_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.deposits[token_i] = self.deposits[token_i].checked_add(v).ok_or(throw!())?)
|
Ok(self.deposits[token_i] = self.deposits[token_i].checked_add(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
pub fn checked_sub_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
pub fn checked_sub_deposit(&mut self, token_i: usize, v: U64F64) -> MangoResult<()> {
|
||||||
Ok(self.deposits[token_i] = self.deposits[token_i].checked_sub(v).ok_or(throw!())?)
|
Ok(self.deposits[token_i] = self.deposits[token_i].checked_sub(v).ok_or(throw!())?)
|
||||||
}
|
}
|
||||||
|
@ -717,6 +712,7 @@ pub fn load_open_orders<'a>(
|
||||||
Ok(Ref::map(strip_dex_padding(acc)?, from_bytes))
|
Ok(Ref::map(strip_dex_padding(acc)?, from_bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn check_open_orders(
|
pub fn check_open_orders(
|
||||||
acc: &AccountInfo,
|
acc: &AccountInfo,
|
||||||
owner: &Pubkey
|
owner: &Pubkey
|
||||||
|
|
Loading…
Reference in New Issue