Skip to content

Commit

Permalink
No longer requires the fee vault, now records the fee on the bank ins…
Browse files Browse the repository at this point in the history
…tead of transfer
  • Loading branch information
jgur-psyops committed Aug 28, 2024
1 parent 2f214cd commit de369bc
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 36 deletions.
1 change: 0 additions & 1 deletion clients/rust/marginfi-cli/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2095,7 +2095,6 @@ pub fn marginfi_account_borrow(
&config.program_id,
)
.0,
fee_vault: find_bank_vault_pda(&bank_pk, BankVaultType::Fee, &config.program_id).0,
}
.to_account_metas(Some(true)),
data: marginfi::instruction::LendingAccountBorrow { amount }.data(),
Expand Down
1 change: 0 additions & 1 deletion programs/marginfi/fuzz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,6 @@ impl<'state> MarginfiFuzzContext<'state> {
))?,
bank_liquidity_vault_authority: ails(bank.liquidity_vault_authority.clone()),
bank_liquidity_vault: InterfaceAccount::try_from(airls(&bank.liquidity_vault))?,
fee_vault: InterfaceAccount::try_from(airls(&bank.fee_vault))?,
},
aisls(&remaining_accounts),
Default::default(),
Expand Down
42 changes: 12 additions & 30 deletions programs/marginfi/src/instructions/marginfi_account/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
};
use anchor_lang::prelude::*;
use anchor_spl::token_interface::{TokenAccount, TokenInterface};
use fixed::types::I80F48;
use fixed::{traits::Fixed, types::I80F48};
use solana_program::{clock::Clock, sysvar::Sysvar};

/// 1. Accrue interest
Expand All @@ -33,7 +33,6 @@ pub fn lending_account_borrow<'info>(
token_program,
bank_liquidity_vault_authority,
bank: bank_loader,
fee_vault,
..
} = ctx.accounts;
let clock = Clock::get()?;
Expand All @@ -56,6 +55,7 @@ pub fn lending_account_borrow<'info>(
bank_loader.key(),
)?;

let mut origination_fee: I80F48 = I80F48::ZERO;
{
let mut bank = bank_loader.load_mut()?;

Expand Down Expand Up @@ -87,29 +87,13 @@ pub fn lending_account_borrow<'info>(

let origination_fee_u64: u64;
if !origination_fee_rate.is_zero() {
let origination_fee: I80F48 = I80F48::from_num(amount_pre_fee)
origination_fee = I80F48::from_num(amount_pre_fee)
.checked_mul(origination_fee_rate)
.ok_or_else(math_error!())?;
.ok_or_else(math_error!())?;
origination_fee_u64 = origination_fee.checked_to_num().ok_or_else(math_error!())?;

// Incurs a borrow that includes the origination fee (but withdraws just the amt)
bank_account.borrow(I80F48::from_num(amount_pre_fee) + origination_fee)?;

// The bank fee account gains the origination fee
bank_account.withdraw_spl_transfer(
origination_fee_u64,
bank_liquidity_vault.to_account_info(),
fee_vault.to_account_info(),
bank_liquidity_vault_authority.to_account_info(),
maybe_bank_mint.as_ref(),
token_program.to_account_info(),
bank_signer!(
BankVaultType::Liquidity,
bank_loader.key(),
liquidity_vault_authority_bump
),
ctx.remaining_accounts,
)?;
} else {
// Incurs a borrow for the amount without any fee
origination_fee_u64 = 0;
Expand Down Expand Up @@ -142,6 +126,14 @@ pub fn lending_account_borrow<'info>(
mint: bank.mint,
amount: amount_pre_fee + origination_fee_u64,
});
} // release mutable borrow of bank

// The bank fee account gains the origination fee
{
let mut bank = bank_loader.load_mut()?;
let bank_fees_before: I80F48 = bank.collected_group_fees_outstanding.into();
let bank_fees_after: I80F48 = bank_fees_before.saturating_add(origination_fee);
bank.collected_group_fees_outstanding = bank_fees_after.into();
}

// Check account health, if below threshold fail transaction
Expand Down Expand Up @@ -196,15 +188,5 @@ pub struct LendingAccountBorrow<'info> {
)]
pub bank_liquidity_vault: InterfaceAccount<'info, TokenAccount>,

#[account(
mut,
seeds = [
FEE_VAULT_SEED.as_bytes(),
bank.key().as_ref(),
],
bump,
)]
pub fee_vault: InterfaceAccount<'info, TokenAccount>,

pub token_program: Interface<'info, TokenInterface>,
}
21 changes: 18 additions & 3 deletions programs/marginfi/tests/user_actions/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ async fn marginfi_account_borrow_success(
.balance()
.await;
let pre_user_debt_accounted = I80F48::ZERO;
let pre_fee_balance: I80F48 = debt_bank_f
.load()
.await
.collected_group_fees_outstanding
.into();

let res = user_mfi_account_f
.try_bank_borrow(user_debt_token_account_f.key, debt_bank_f, borrow_amount)
Expand Down Expand Up @@ -130,25 +135,35 @@ async fn marginfi_account_borrow_success(
let origination_fee: I80F48 = I80F48::from_num(borrow_amount_native)
.checked_mul(origination_fee_rate)
.unwrap();
let origination_fee_i64: i64 = origination_fee.checked_to_num().expect("out of bounds");

let active_balance_count = marginfi_account
.lending_account
.get_active_balances_iter()
.count();
assert_eq!(2, active_balance_count);

let expected_liquidity_vault_delta = -(borrow_amount_pre_fee as i64 + origination_fee_i64);
let expected_liquidity_vault_delta = -(borrow_amount_pre_fee as i64);
let actual_liquidity_vault_delta = post_vault_balance as i64 - pre_vault_balance as i64;
let accounted_user_balance_delta = post_user_debt_accounted - pre_user_debt_accounted;

// The liquidity vault paid out just the pre-origination fee amount (e.g. what the user borrowed
// before accounting for the fee)
assert_eq!(expected_liquidity_vault_delta, actual_liquidity_vault_delta);
assert_eq_with_tolerance!(
I80F48::from(expected_liquidity_vault_delta),
// Note: the user still gains debt which includes the origination fee
I80F48::from(expected_liquidity_vault_delta) - origination_fee,
-accounted_user_balance_delta,
1
);

// The outstanding origination fee is recorded
let post_fee_balance: I80F48 = debt_bank_f
.load()
.await
.collected_group_fees_outstanding
.into();
assert_eq!(pre_fee_balance + origination_fee, post_fee_balance);

Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion test-utils/src/marginfi_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ impl MarginfiAccountFixture {
destination_token_account: destination_account,
bank_liquidity_vault: bank.get_vault(BankVaultType::Liquidity).0,
bank_liquidity_vault_authority: bank.get_vault_authority(BankVaultType::Liquidity).0,
fee_vault: bank.get_vault(BankVaultType::Fee).0,
token_program: bank.get_token_program(),
}
.to_account_metas(Some(true));
Expand Down

0 comments on commit de369bc

Please sign in to comment.