Add loan amount to WithdrawLoanLog. Add withdraw loan logging to toke… (#599)
* Add loan amount to WithdrawLoanLog. Add withdraw loan logging to token_force_close_borrows_with_token * Address review comments.
This commit is contained in:
parent
7803f1dc9d
commit
defbd8c2b1
|
@ -9,7 +9,7 @@ use crate::state::*;
|
||||||
use super::{apply_settle_changes, OpenOrdersAmounts, OpenOrdersSlim};
|
use super::{apply_settle_changes, OpenOrdersAmounts, OpenOrdersSlim};
|
||||||
use crate::accounts_ix::*;
|
use crate::accounts_ix::*;
|
||||||
use crate::logs::Serum3OpenOrdersBalanceLogV2;
|
use crate::logs::Serum3OpenOrdersBalanceLogV2;
|
||||||
use crate::logs::{LoanOriginationFeeInstruction, WithdrawLoanOriginationFeeLog};
|
use crate::logs::{LoanOriginationFeeInstruction, WithdrawLoanLog};
|
||||||
|
|
||||||
/// Settling means moving free funds from the serum3 open orders account
|
/// Settling means moving free funds from the serum3 open orders account
|
||||||
/// back into the mango account wallet.
|
/// back into the mango account wallet.
|
||||||
|
@ -171,17 +171,18 @@ pub fn charge_loan_origination_fees(
|
||||||
// now that the loan is actually materialized, charge the loan origination fee
|
// now that the loan is actually materialized, charge the loan origination fee
|
||||||
// note: the withdraw has already happened while placing the order
|
// note: the withdraw has already happened while placing the order
|
||||||
let base_token_account = account.token_position_mut(base_bank.token_index)?.0;
|
let base_token_account = account.token_position_mut(base_bank.token_index)?.0;
|
||||||
let (_, fee) = base_bank.withdraw_loan_origination_fee(
|
let withdraw_result = base_bank.withdraw_loan_origination_fee(
|
||||||
base_token_account,
|
base_token_account,
|
||||||
actualized_base_loan,
|
actualized_base_loan,
|
||||||
now_ts,
|
now_ts,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
emit!(WithdrawLoanOriginationFeeLog {
|
emit!(WithdrawLoanLog {
|
||||||
mango_group: *group_pubkey,
|
mango_group: *group_pubkey,
|
||||||
mango_account: *account_pubkey,
|
mango_account: *account_pubkey,
|
||||||
token_index: base_bank.token_index,
|
token_index: base_bank.token_index,
|
||||||
loan_origination_fee: fee.to_bits(),
|
loan_amount: withdraw_result.loan_amount.to_bits(),
|
||||||
|
loan_origination_fee: withdraw_result.loan_origination_fee.to_bits(),
|
||||||
instruction: LoanOriginationFeeInstruction::Serum3SettleFunds,
|
instruction: LoanOriginationFeeInstruction::Serum3SettleFunds,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -199,17 +200,18 @@ pub fn charge_loan_origination_fees(
|
||||||
// now that the loan is actually materialized, charge the loan origination fee
|
// now that the loan is actually materialized, charge the loan origination fee
|
||||||
// note: the withdraw has already happened while placing the order
|
// note: the withdraw has already happened while placing the order
|
||||||
let quote_token_account = account.token_position_mut(quote_bank.token_index)?.0;
|
let quote_token_account = account.token_position_mut(quote_bank.token_index)?.0;
|
||||||
let (_, fee) = quote_bank.withdraw_loan_origination_fee(
|
let withdraw_result = quote_bank.withdraw_loan_origination_fee(
|
||||||
quote_token_account,
|
quote_token_account,
|
||||||
actualized_quote_loan,
|
actualized_quote_loan,
|
||||||
now_ts,
|
now_ts,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
emit!(WithdrawLoanOriginationFeeLog {
|
emit!(WithdrawLoanLog {
|
||||||
mango_group: *group_pubkey,
|
mango_group: *group_pubkey,
|
||||||
mango_account: *account_pubkey,
|
mango_account: *account_pubkey,
|
||||||
token_index: quote_bank.token_index,
|
token_index: quote_bank.token_index,
|
||||||
loan_origination_fee: fee.to_bits(),
|
loan_amount: withdraw_result.loan_amount.to_bits(),
|
||||||
|
loan_origination_fee: withdraw_result.loan_origination_fee.to_bits(),
|
||||||
instruction: LoanOriginationFeeInstruction::Serum3SettleFunds,
|
instruction: LoanOriginationFeeInstruction::Serum3SettleFunds,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ pub fn token_force_close_borrows_with_token(
|
||||||
liab_bank.deposit_with_dusting(liqee_liab_position, liab_transfer, now_ts)?;
|
liab_bank.deposit_with_dusting(liqee_liab_position, liab_transfer, now_ts)?;
|
||||||
let liqee_liab_indexed_position = liqee_liab_position.indexed_position;
|
let liqee_liab_indexed_position = liqee_liab_position.indexed_position;
|
||||||
|
|
||||||
let (liqor_liab_active, loan_origination_fee) =
|
let liqor_liab_withdraw_result =
|
||||||
liab_bank.withdraw_with_fee(liqor_liab_position, liab_transfer, now_ts)?;
|
liab_bank.withdraw_with_fee(liqor_liab_position, liab_transfer, now_ts)?;
|
||||||
let liqor_liab_indexed_position = liqor_liab_position.indexed_position;
|
let liqor_liab_indexed_position = liqor_liab_position.indexed_position;
|
||||||
let liqee_liab_native_after = liqee_liab_position.native(liab_bank);
|
let liqee_liab_native_after = liqee_liab_position.native(liab_bank);
|
||||||
|
@ -174,6 +174,12 @@ pub fn token_force_close_borrows_with_token(
|
||||||
fee_factor: fee_factor.to_bits(),
|
fee_factor: fee_factor.to_bits(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// liqor should never have a borrow
|
||||||
|
require!(
|
||||||
|
liqor_liab_withdraw_result.loan_amount.is_zero(),
|
||||||
|
MangoError::SomeError
|
||||||
|
);
|
||||||
|
|
||||||
let liqee_health_cache = new_health_cache(&liqee.borrow(), &mut account_retriever)
|
let liqee_health_cache = new_health_cache(&liqee.borrow(), &mut account_retriever)
|
||||||
.context("create liqee health cache")?;
|
.context("create liqee health cache")?;
|
||||||
let liqee_liq_end_health = liqee_health_cache.health(HealthType::LiquidationEnd);
|
let liqee_liq_end_health = liqee_health_cache.health(HealthType::LiquidationEnd);
|
||||||
|
@ -191,7 +197,7 @@ pub fn token_force_close_borrows_with_token(
|
||||||
if !liqor_asset_active {
|
if !liqor_asset_active {
|
||||||
liqor.deactivate_token_position_and_log(liqor_asset_raw_index, liqor_key);
|
liqor.deactivate_token_position_and_log(liqor_asset_raw_index, liqor_key);
|
||||||
}
|
}
|
||||||
if !liqor_liab_active {
|
if !liqor_liab_withdraw_result.position_is_active {
|
||||||
liqor.deactivate_token_position_and_log(liqor_liab_raw_index, liqor_key)
|
liqor.deactivate_token_position_and_log(liqor_liab_raw_index, liqor_key)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,8 +9,7 @@ use crate::state::*;
|
||||||
|
|
||||||
use crate::accounts_ix::*;
|
use crate::accounts_ix::*;
|
||||||
use crate::logs::{
|
use crate::logs::{
|
||||||
LoanOriginationFeeInstruction, TokenBalanceLog, TokenLiqBankruptcyLog,
|
LoanOriginationFeeInstruction, TokenBalanceLog, TokenLiqBankruptcyLog, WithdrawLoanLog,
|
||||||
WithdrawLoanOriginationFeeLog,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn token_liq_bankruptcy(
|
pub fn token_liq_bankruptcy(
|
||||||
|
@ -149,7 +148,7 @@ pub fn token_liq_bankruptcy(
|
||||||
// transfer liab from liqee to liqor
|
// transfer liab from liqee to liqor
|
||||||
let (liqor_liab, liqor_liab_raw_token_index, _) =
|
let (liqor_liab, liqor_liab_raw_token_index, _) =
|
||||||
liqor.ensure_token_position(liab_token_index)?;
|
liqor.ensure_token_position(liab_token_index)?;
|
||||||
let (liqor_liab_active, loan_origination_fee) =
|
let liqor_liab_withdraw_result =
|
||||||
liab_bank.withdraw_with_fee(liqor_liab, liab_transfer, now_ts)?;
|
liab_bank.withdraw_with_fee(liqor_liab, liab_transfer, now_ts)?;
|
||||||
|
|
||||||
// liqor liab
|
// liqor liab
|
||||||
|
@ -169,12 +168,16 @@ pub fn token_liq_bankruptcy(
|
||||||
require!(liqor_health >= 0, MangoError::HealthMustBePositive);
|
require!(liqor_health >= 0, MangoError::HealthMustBePositive);
|
||||||
}
|
}
|
||||||
|
|
||||||
if loan_origination_fee.is_positive() {
|
if liqor_liab_withdraw_result
|
||||||
emit!(WithdrawLoanOriginationFeeLog {
|
.loan_origination_fee
|
||||||
|
.is_positive()
|
||||||
|
{
|
||||||
|
emit!(WithdrawLoanLog {
|
||||||
mango_group: ctx.accounts.group.key(),
|
mango_group: ctx.accounts.group.key(),
|
||||||
mango_account: ctx.accounts.liqor.key(),
|
mango_account: ctx.accounts.liqor.key(),
|
||||||
token_index: liab_token_index,
|
token_index: liab_token_index,
|
||||||
loan_origination_fee: loan_origination_fee.to_bits(),
|
loan_amount: liqor_liab_withdraw_result.loan_amount.to_bits(),
|
||||||
|
loan_origination_fee: liqor_liab_withdraw_result.loan_origination_fee.to_bits(),
|
||||||
instruction: LoanOriginationFeeInstruction::LiqTokenBankruptcy
|
instruction: LoanOriginationFeeInstruction::LiqTokenBankruptcy
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -185,7 +188,7 @@ pub fn token_liq_bankruptcy(
|
||||||
ctx.accounts.liqor.key(),
|
ctx.accounts.liqor.key(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if !liqor_liab_active {
|
if !liqor_liab_withdraw_result.position_is_active {
|
||||||
liqor.deactivate_token_position_and_log(
|
liqor.deactivate_token_position_and_log(
|
||||||
liqor_liab_raw_token_index,
|
liqor_liab_raw_token_index,
|
||||||
ctx.accounts.liqor.key(),
|
ctx.accounts.liqor.key(),
|
||||||
|
|
|
@ -5,8 +5,7 @@ use crate::accounts_ix::*;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::health::*;
|
use crate::health::*;
|
||||||
use crate::logs::{
|
use crate::logs::{
|
||||||
LoanOriginationFeeInstruction, TokenBalanceLog, TokenLiqWithTokenLog,
|
LoanOriginationFeeInstruction, TokenBalanceLog, TokenLiqWithTokenLog, WithdrawLoanLog,
|
||||||
WithdrawLoanOriginationFeeLog,
|
|
||||||
};
|
};
|
||||||
use crate::state::*;
|
use crate::state::*;
|
||||||
|
|
||||||
|
@ -221,7 +220,7 @@ pub(crate) fn liquidation_action(
|
||||||
|
|
||||||
let (liqor_liab_position, liqor_liab_raw_index, _) =
|
let (liqor_liab_position, liqor_liab_raw_index, _) =
|
||||||
liqor.ensure_token_position(liab_token_index)?;
|
liqor.ensure_token_position(liab_token_index)?;
|
||||||
let (liqor_liab_active, loan_origination_fee) =
|
let liqor_liab_withdraw_result =
|
||||||
liab_bank.withdraw_with_fee(liqor_liab_position, liab_transfer, now_ts)?;
|
liab_bank.withdraw_with_fee(liqor_liab_position, liab_transfer, now_ts)?;
|
||||||
let liqor_liab_indexed_position = liqor_liab_position.indexed_position;
|
let liqor_liab_indexed_position = liqor_liab_position.indexed_position;
|
||||||
let liqee_liab_native_after = liqee_liab_position.native(liab_bank);
|
let liqee_liab_native_after = liqee_liab_position.native(liab_bank);
|
||||||
|
@ -289,12 +288,16 @@ pub(crate) fn liquidation_action(
|
||||||
borrow_index: liab_bank.borrow_index.to_bits(),
|
borrow_index: liab_bank.borrow_index.to_bits(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if loan_origination_fee.is_positive() {
|
if liqor_liab_withdraw_result
|
||||||
emit!(WithdrawLoanOriginationFeeLog {
|
.loan_origination_fee
|
||||||
|
.is_positive()
|
||||||
|
{
|
||||||
|
emit!(WithdrawLoanLog {
|
||||||
mango_group: liqee.fixed.group,
|
mango_group: liqee.fixed.group,
|
||||||
mango_account: liqor_key,
|
mango_account: liqor_key,
|
||||||
token_index: liab_token_index,
|
token_index: liab_token_index,
|
||||||
loan_origination_fee: loan_origination_fee.to_bits(),
|
loan_amount: liqor_liab_withdraw_result.loan_amount.to_bits(),
|
||||||
|
loan_origination_fee: liqor_liab_withdraw_result.loan_origination_fee.to_bits(),
|
||||||
instruction: LoanOriginationFeeInstruction::LiqTokenWithToken
|
instruction: LoanOriginationFeeInstruction::LiqTokenWithToken
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -309,7 +312,7 @@ pub(crate) fn liquidation_action(
|
||||||
if !liqor_asset_active {
|
if !liqor_asset_active {
|
||||||
liqor.deactivate_token_position_and_log(liqor_asset_raw_index, liqor_key);
|
liqor.deactivate_token_position_and_log(liqor_asset_raw_index, liqor_key);
|
||||||
}
|
}
|
||||||
if !liqor_liab_active {
|
if !liqor_liab_withdraw_result.position_is_active {
|
||||||
liqor.deactivate_token_position_and_log(liqor_liab_raw_index, liqor_key)
|
liqor.deactivate_token_position_and_log(liqor_liab_raw_index, liqor_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,7 @@ use anchor_spl::token;
|
||||||
use fixed::types::I80F48;
|
use fixed::types::I80F48;
|
||||||
|
|
||||||
use crate::accounts_ix::*;
|
use crate::accounts_ix::*;
|
||||||
use crate::logs::{
|
use crate::logs::{LoanOriginationFeeInstruction, TokenBalanceLog, WithdrawLoanLog, WithdrawLog};
|
||||||
LoanOriginationFeeInstruction, TokenBalanceLog, WithdrawLoanOriginationFeeLog, WithdrawLog,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn token_withdraw(ctx: Context<TokenWithdraw>, amount: u64, allow_borrow: bool) -> Result<()> {
|
pub fn token_withdraw(ctx: Context<TokenWithdraw>, amount: u64, allow_borrow: bool) -> Result<()> {
|
||||||
require_msg!(amount > 0, "withdraw amount must be positive");
|
require_msg!(amount > 0, "withdraw amount must be positive");
|
||||||
|
@ -65,7 +63,7 @@ pub fn token_withdraw(ctx: Context<TokenWithdraw>, amount: u64, allow_borrow: bo
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Update the bank and position
|
// Update the bank and position
|
||||||
let (position_is_active, loan_origination_fee) = bank.withdraw_with_fee(
|
let withdraw_result = bank.withdraw_with_fee(
|
||||||
position,
|
position,
|
||||||
amount_i80f48,
|
amount_i80f48,
|
||||||
Clock::get()?.unix_timestamp.try_into().unwrap(),
|
Clock::get()?.unix_timestamp.try_into().unwrap(),
|
||||||
|
@ -116,7 +114,7 @@ pub fn token_withdraw(ctx: Context<TokenWithdraw>, amount: u64, allow_borrow: bo
|
||||||
// remaining_accounts for all banks/oracles, including the account that will now be
|
// remaining_accounts for all banks/oracles, including the account that will now be
|
||||||
// deactivated.
|
// deactivated.
|
||||||
//
|
//
|
||||||
if !position_is_active {
|
if !withdraw_result.position_is_active {
|
||||||
account.deactivate_token_position_and_log(raw_token_index, ctx.accounts.account.key());
|
account.deactivate_token_position_and_log(raw_token_index, ctx.accounts.account.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,12 +127,13 @@ pub fn token_withdraw(ctx: Context<TokenWithdraw>, amount: u64, allow_borrow: bo
|
||||||
price: oracle_price.to_bits(),
|
price: oracle_price.to_bits(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if loan_origination_fee.is_positive() {
|
if withdraw_result.loan_origination_fee.is_positive() {
|
||||||
emit!(WithdrawLoanOriginationFeeLog {
|
emit!(WithdrawLoanLog {
|
||||||
mango_group: ctx.accounts.group.key(),
|
mango_group: ctx.accounts.group.key(),
|
||||||
mango_account: ctx.accounts.account.key(),
|
mango_account: ctx.accounts.account.key(),
|
||||||
token_index,
|
token_index,
|
||||||
loan_origination_fee: loan_origination_fee.to_bits(),
|
loan_amount: withdraw_result.loan_amount.to_bits(),
|
||||||
|
loan_origination_fee: withdraw_result.loan_origination_fee.to_bits(),
|
||||||
instruction: LoanOriginationFeeInstruction::TokenWithdraw,
|
instruction: LoanOriginationFeeInstruction::TokenWithdraw,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,16 @@ pub struct WithdrawLoanOriginationFeeLog {
|
||||||
pub instruction: LoanOriginationFeeInstruction,
|
pub instruction: LoanOriginationFeeInstruction,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[event]
|
||||||
|
pub struct WithdrawLoanLog {
|
||||||
|
pub mango_group: Pubkey,
|
||||||
|
pub mango_account: Pubkey,
|
||||||
|
pub token_index: u16,
|
||||||
|
pub loan_amount: i128,
|
||||||
|
pub loan_origination_fee: i128,
|
||||||
|
pub instruction: LoanOriginationFeeInstruction,
|
||||||
|
}
|
||||||
|
|
||||||
#[event]
|
#[event]
|
||||||
pub struct TokenLiqBankruptcyLog {
|
pub struct TokenLiqBankruptcyLog {
|
||||||
pub mango_group: Pubkey,
|
pub mango_group: Pubkey,
|
||||||
|
|
|
@ -170,6 +170,12 @@ const_assert_eq!(
|
||||||
const_assert_eq!(size_of::<Bank>(), 3064);
|
const_assert_eq!(size_of::<Bank>(), 3064);
|
||||||
const_assert_eq!(size_of::<Bank>() % 8, 0);
|
const_assert_eq!(size_of::<Bank>() % 8, 0);
|
||||||
|
|
||||||
|
pub struct WithdrawResult {
|
||||||
|
pub position_is_active: bool,
|
||||||
|
pub loan_origination_fee: I80F48,
|
||||||
|
pub loan_amount: I80F48,
|
||||||
|
}
|
||||||
|
|
||||||
impl Bank {
|
impl Bank {
|
||||||
pub fn from_existing_bank(
|
pub fn from_existing_bank(
|
||||||
existing_bank: &Bank,
|
existing_bank: &Bank,
|
||||||
|
@ -403,13 +409,15 @@ impl Bank {
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
let (position_is_active, _) = self.withdraw_internal_wrapper(
|
let position_is_active = self
|
||||||
position,
|
.withdraw_internal_wrapper(
|
||||||
native_amount,
|
position,
|
||||||
false,
|
native_amount,
|
||||||
!position.is_in_use(),
|
false,
|
||||||
now_ts,
|
!position.is_in_use(),
|
||||||
)?;
|
now_ts,
|
||||||
|
)?
|
||||||
|
.position_is_active;
|
||||||
|
|
||||||
Ok(position_is_active)
|
Ok(position_is_active)
|
||||||
}
|
}
|
||||||
|
@ -424,7 +432,7 @@ impl Bank {
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
self.withdraw_internal_wrapper(position, native_amount, false, true, now_ts)
|
self.withdraw_internal_wrapper(position, native_amount, false, true, now_ts)
|
||||||
.map(|(not_dusted, _)| not_dusted || position.is_in_use())
|
.map(|withdraw_result| withdraw_result.position_is_active || position.is_in_use())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Withdraws `native_amount` while applying the loan origination fee if a borrow is created.
|
/// Withdraws `native_amount` while applying the loan origination fee if a borrow is created.
|
||||||
|
@ -440,7 +448,7 @@ impl Bank {
|
||||||
position: &mut TokenPosition,
|
position: &mut TokenPosition,
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<(bool, I80F48)> {
|
) -> Result<WithdrawResult> {
|
||||||
self.withdraw_internal_wrapper(position, native_amount, true, !position.is_in_use(), now_ts)
|
self.withdraw_internal_wrapper(position, native_amount, true, !position.is_in_use(), now_ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +460,7 @@ impl Bank {
|
||||||
with_loan_origination_fee: bool,
|
with_loan_origination_fee: bool,
|
||||||
allow_dusting: bool,
|
allow_dusting: bool,
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<(bool, I80F48)> {
|
) -> Result<WithdrawResult> {
|
||||||
let opening_indexed_position = position.indexed_position;
|
let opening_indexed_position = position.indexed_position;
|
||||||
let res = self.withdraw_internal(
|
let res = self.withdraw_internal(
|
||||||
position,
|
position,
|
||||||
|
@ -473,7 +481,7 @@ impl Bank {
|
||||||
with_loan_origination_fee: bool,
|
with_loan_origination_fee: bool,
|
||||||
allow_dusting: bool,
|
allow_dusting: bool,
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<(bool, I80F48)> {
|
) -> Result<WithdrawResult> {
|
||||||
require_gte!(native_amount, 0);
|
require_gte!(native_amount, 0);
|
||||||
let native_position = position.native(self);
|
let native_position = position.native(self);
|
||||||
|
|
||||||
|
@ -486,13 +494,21 @@ impl Bank {
|
||||||
self.dust += new_native_position;
|
self.dust += new_native_position;
|
||||||
self.indexed_deposits -= position.indexed_position;
|
self.indexed_deposits -= position.indexed_position;
|
||||||
position.indexed_position = I80F48::ZERO;
|
position.indexed_position = I80F48::ZERO;
|
||||||
return Ok((false, I80F48::ZERO));
|
return Ok(WithdrawResult {
|
||||||
|
position_is_active: false,
|
||||||
|
loan_origination_fee: I80F48::ZERO,
|
||||||
|
loan_amount: I80F48::ZERO,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// withdraw some deposits leaving a positive balance
|
// withdraw some deposits leaving a positive balance
|
||||||
let indexed_change = native_amount / self.deposit_index;
|
let indexed_change = native_amount / self.deposit_index;
|
||||||
self.indexed_deposits -= indexed_change;
|
self.indexed_deposits -= indexed_change;
|
||||||
position.indexed_position -= indexed_change;
|
position.indexed_position -= indexed_change;
|
||||||
return Ok((true, I80F48::ZERO));
|
return Ok(WithdrawResult {
|
||||||
|
position_is_active: true,
|
||||||
|
loan_origination_fee: I80F48::ZERO,
|
||||||
|
loan_amount: I80F48::ZERO,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +535,11 @@ impl Bank {
|
||||||
// withdraws and not borrows
|
// withdraws and not borrows
|
||||||
self.update_net_borrows(native_amount, now_ts);
|
self.update_net_borrows(native_amount, now_ts);
|
||||||
|
|
||||||
Ok((true, loan_origination_fee))
|
Ok(WithdrawResult {
|
||||||
|
position_is_active: true,
|
||||||
|
loan_origination_fee,
|
||||||
|
loan_amount: native_amount,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// withdraw the loan origination fee for a borrow that happenend earlier
|
// withdraw the loan origination fee for a borrow that happenend earlier
|
||||||
|
@ -528,19 +548,26 @@ impl Bank {
|
||||||
position: &mut TokenPosition,
|
position: &mut TokenPosition,
|
||||||
already_borrowed_native_amount: I80F48,
|
already_borrowed_native_amount: I80F48,
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<(bool, I80F48)> {
|
) -> Result<WithdrawResult> {
|
||||||
let loan_origination_fee = self.loan_origination_fee_rate * already_borrowed_native_amount;
|
let loan_origination_fee = self.loan_origination_fee_rate * already_borrowed_native_amount;
|
||||||
self.collected_fees_native += loan_origination_fee;
|
self.collected_fees_native += loan_origination_fee;
|
||||||
|
|
||||||
let (position_is_active, _) = self.withdraw_internal_wrapper(
|
let position_is_active = self
|
||||||
position,
|
.withdraw_internal_wrapper(
|
||||||
loan_origination_fee,
|
position,
|
||||||
false,
|
loan_origination_fee,
|
||||||
!position.is_in_use(),
|
false,
|
||||||
now_ts,
|
!position.is_in_use(),
|
||||||
)?;
|
now_ts,
|
||||||
|
)?
|
||||||
|
.position_is_active;
|
||||||
|
|
||||||
Ok((position_is_active, loan_origination_fee))
|
Ok(WithdrawResult {
|
||||||
|
position_is_active,
|
||||||
|
loan_origination_fee,
|
||||||
|
// To avoid double counting of loans return loan_amount of 0 here (as the loan_amount has already been returned earlier with loan_origination_fee == 0)
|
||||||
|
loan_amount: I80F48::ZERO,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change a position without applying the loan origination fee
|
/// Change a position without applying the loan origination fee
|
||||||
|
@ -563,9 +590,13 @@ impl Bank {
|
||||||
position: &mut TokenPosition,
|
position: &mut TokenPosition,
|
||||||
native_amount: I80F48,
|
native_amount: I80F48,
|
||||||
now_ts: u64,
|
now_ts: u64,
|
||||||
) -> Result<(bool, I80F48)> {
|
) -> Result<WithdrawResult> {
|
||||||
if native_amount >= 0 {
|
if native_amount >= 0 {
|
||||||
Ok((self.deposit(position, native_amount, now_ts)?, I80F48::ZERO))
|
Ok(WithdrawResult {
|
||||||
|
position_is_active: self.deposit(position, native_amount, now_ts)?,
|
||||||
|
loan_origination_fee: I80F48::ZERO,
|
||||||
|
loan_amount: I80F48::ZERO,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
self.withdraw_with_fee(position, -native_amount, now_ts)
|
self.withdraw_with_fee(position, -native_amount, now_ts)
|
||||||
}
|
}
|
||||||
|
@ -948,7 +979,9 @@ mod tests {
|
||||||
let change = I80F48::from(change);
|
let change = I80F48::from(change);
|
||||||
let dummy_now_ts = 1 as u64;
|
let dummy_now_ts = 1 as u64;
|
||||||
let dummy_price = I80F48::ZERO;
|
let dummy_price = I80F48::ZERO;
|
||||||
let (is_active, _) = bank.change_with_fee(&mut account, change, dummy_now_ts)?;
|
let is_active = bank
|
||||||
|
.change_with_fee(&mut account, change, dummy_now_ts)?
|
||||||
|
.position_is_active;
|
||||||
|
|
||||||
let mut expected_native = start_native + change;
|
let mut expected_native = start_native + change;
|
||||||
if expected_native >= 0.0 && expected_native < 1.0 && !is_in_use {
|
if expected_native >= 0.0 && expected_native < 1.0 && !is_in_use {
|
||||||
|
|
Loading…
Reference in New Issue