Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deposit up to limit functionality #275

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions clients/rust/marginfi-cli/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ pub enum AccountCommand {
Deposit {
bank: Pubkey,
ui_amount: f64,
deposit_up_to_limit: Option<bool>,
},
Withdraw {
bank: Pubkey,
Expand Down Expand Up @@ -953,9 +954,17 @@ fn process_account_subcmd(subcmd: AccountCommand, global_options: &GlobalOptions
AccountCommand::Get { account } => {
processor::marginfi_account_get(profile, &config, account)
}
AccountCommand::Deposit { bank, ui_amount } => {
processor::marginfi_account_deposit(&profile, &config, bank, ui_amount)
}
AccountCommand::Deposit {
bank,
ui_amount,
deposit_up_to_limit,
} => processor::marginfi_account_deposit(
&profile,
&config,
bank,
ui_amount,
deposit_up_to_limit,
),
AccountCommand::Withdraw {
bank,
ui_amount,
Expand Down
7 changes: 6 additions & 1 deletion clients/rust/marginfi-cli/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,7 @@ pub fn marginfi_account_deposit(
config: &Config,
bank_pk: Pubkey,
ui_amount: f64,
deposit_up_to_limit: Option<bool>,
) -> Result<()> {
let rpc_client = config.mfi_program.rpc();
let signer = config.get_non_ms_authority_keypair()?;
Expand Down Expand Up @@ -2094,7 +2095,11 @@ pub fn marginfi_account_deposit(
token_program,
}
.to_account_metas(Some(true)),
data: marginfi::instruction::LendingAccountDeposit { amount }.data(),
data: marginfi::instruction::LendingAccountDeposit {
amount,
deposit_up_to_limit,
}
.data(),
};
if token_program == spl_token_2022::ID {
ix.accounts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub fn process<'info>(
return Err(ProgramError::InvalidAccountData.into());
}

marginfi::cpi::lending_account_deposit(cpi_ctx, amount)?;
marginfi::cpi::lending_account_deposit(cpi_ctx, amount, None)?;

close_account(CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
Expand Down
4 changes: 2 additions & 2 deletions programs/liquidity-incentive-program/tests/lip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ async fn campaign_mixed_yield() -> Result<()> {
let sol_funding_account = test_f.sol_mint.create_token_account_and_mint_to(1000).await;

borrower
.try_bank_deposit(sol_funding_account.key, &sol_bank, 1000)
.try_bank_deposit(sol_funding_account.key, &sol_bank, 1000, None)
.await?;

let usdc_borrowing_account = test_f
Expand Down Expand Up @@ -243,7 +243,7 @@ async fn campaign_max_yield() -> Result<()> {
let sol_funding_account = test_f.sol_mint.create_token_account_and_mint_to(1000).await;

borrower
.try_bank_deposit(sol_funding_account.key, &sol_bank, 1000)
.try_bank_deposit(sol_funding_account.key, &sol_bank, 1000, None)
.await?;

let usdc_borrowing_account = test_f
Expand Down
4 changes: 3 additions & 1 deletion programs/marginfi/fuzz/fuzz_targets/lend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum Action {
account: AccountIdx,
bank: BankIdx,
asset_amount: AssetAmount,
deposit_up_to_limit: bool,
},
Borrow {
account: AccountIdx,
Expand Down Expand Up @@ -199,7 +200,8 @@ fn process_action<'bump>(action: &Action, mga: &'bump MarginfiFuzzContext<'bump>
account,
bank,
asset_amount,
} => mga.process_action_deposit(account, bank, asset_amount)?,
deposit_up_to_limit,
} => mga.process_action_deposit(account, bank, asset_amount, Some(*deposit_up_to_limit))?,
Action::Withdraw {
account,
bank,
Expand Down
21 changes: 12 additions & 9 deletions programs/marginfi/fuzz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ impl<'state> MarginfiFuzzContext<'state> {
* 10_u64
.pow(marginfi_state.banks[bank_idx as usize].mint_decimals.into()),
),
None,
)
.unwrap();
}
Expand Down Expand Up @@ -373,6 +374,7 @@ impl<'state> MarginfiFuzzContext<'state> {
account_idx: &AccountIdx,
bank_idx: &BankIdx,
asset_amount: &AssetAmount,
deposit_up_to_limit: Option<bool>,
) -> anyhow::Result<()> {
let marginfi_account = &self.marginfi_accounts[account_idx.0 as usize];
sort_balances(airls(&marginfi_account.margin_account));
Expand Down Expand Up @@ -411,6 +413,7 @@ impl<'state> MarginfiFuzzContext<'state> {
Default::default(),
),
asset_amount.0,
deposit_up_to_limit,
);

let success = if res.is_err() {
Expand Down Expand Up @@ -1031,7 +1034,7 @@ mod tests {

assert_eq!(al.load().unwrap().admin, a.owner.key());

a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000), None)
.unwrap();

let marginfi_account_ai = AccountLoader::<MarginfiAccount>::try_from_unchecked(
Expand All @@ -1052,9 +1055,9 @@ mod tests {
let account_state = AccountsState::new();
let a = MarginfiFuzzContext::setup(&account_state, &[BankAndOracleConfig::dummy(); 2], 2);

a.process_action_deposit(&AccountIdx(1), &BankIdx(1), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(1), &BankIdx(1), &AssetAmount(1000), None)
.unwrap();
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000), None)
.unwrap();
a.process_action_borrow(&AccountIdx(0), &BankIdx(1), &AssetAmount(100))
.unwrap();
Expand Down Expand Up @@ -1094,9 +1097,9 @@ mod tests {
let account_state = AccountsState::new();
let a = MarginfiFuzzContext::setup(&account_state, &[BankAndOracleConfig::dummy(); 2], 3);

a.process_action_deposit(&AccountIdx(1), &BankIdx(1), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(1), &BankIdx(1), &AssetAmount(1000), None)
.unwrap();
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000), None)
.unwrap();
a.process_action_borrow(&AccountIdx(0), &BankIdx(1), &AssetAmount(500))
.unwrap();
Expand Down Expand Up @@ -1132,7 +1135,7 @@ mod tests {
println!("Health {health}");
}

a.process_action_deposit(&AccountIdx(2), &BankIdx(1), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(2), &BankIdx(1), &AssetAmount(1000), None)
.unwrap();

a.process_liquidate_account(&AccountIdx(2), &AccountIdx(0), &AssetAmount(50))
Expand All @@ -1158,9 +1161,9 @@ mod tests {

let a = MarginfiFuzzContext::setup(&account_state, &[BankAndOracleConfig::dummy(); 2], 3);

a.process_action_deposit(&AccountIdx(1), &BankIdx(1), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(1), &BankIdx(1), &AssetAmount(1000), None)
.unwrap();
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(0), &BankIdx(0), &AssetAmount(1000), None)
.unwrap();
a.process_action_borrow(&AccountIdx(0), &BankIdx(1), &AssetAmount(500))
.unwrap();
Expand Down Expand Up @@ -1192,7 +1195,7 @@ mod tests {
println!("Health {health}");
}

a.process_action_deposit(&AccountIdx(2), &BankIdx(1), &AssetAmount(1000))
a.process_action_deposit(&AccountIdx(2), &BankIdx(1), &AssetAmount(1000), None)
.unwrap();

a.process_liquidate_account(&AccountIdx(2), &AccountIdx(0), &AssetAmount(1000))
Expand Down
42 changes: 38 additions & 4 deletions programs/marginfi/src/instructions/marginfi_account/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
check,
constants::LIQUIDITY_VAULT_SEED,
events::{AccountEventHeader, LendingAccountDepositEvent},
math_error,
prelude::*,
state::{
marginfi_account::{BankAccountWrapper, MarginfiAccount, DISABLED_FLAG},
Expand All @@ -24,6 +25,7 @@ use solana_program::sysvar::Sysvar;
pub fn lending_account_deposit<'info>(
mut ctx: Context<'_, '_, 'info, 'info, LendingAccountDeposit<'info>>,
amount: u64,
deposit_up_to_limit: Option<bool>,
) -> MarginfiResult {
let LendingAccountDeposit {
marginfi_account: marginfi_account_loader,
Expand All @@ -41,6 +43,7 @@ pub fn lending_account_deposit<'info>(
&*bank_loader.load()?,
token_program.key,
)?;
let deposit_up_to_limit = deposit_up_to_limit.unwrap_or(false);

let mut bank = bank_loader.load_mut()?;
let mut marginfi_account = marginfi_account_loader.load_mut()?;
Expand All @@ -52,6 +55,33 @@ pub fn lending_account_deposit<'info>(
MarginfiError::AccountDisabled
);

let deposit_amount = if deposit_up_to_limit && bank.config.is_deposit_limit_active() {
let current_asset_amount = bank.get_asset_amount(bank.total_asset_shares.into())?;
let deposit_limit = I80F48::from_num(bank.config.deposit_limit);

if current_asset_amount >= deposit_limit {
0
} else {
let remaining_capacity = deposit_limit
.checked_sub(current_asset_amount)
.ok_or_else(math_error!())?
.checked_sub(I80F48::ONE) // Subtract 1 to ensure we stay under limit: total_deposits_amount < deposit_limit
.ok_or_else(math_error!())?
.checked_floor()
.ok_or_else(math_error!())?
.checked_to_num::<u64>()
.ok_or_else(math_error!())?;

std::cmp::min(amount, remaining_capacity)
}
} else {
amount
};

if deposit_amount == 0 {
return Ok(());
}

bank.accrue_interest(
clock.unix_timestamp,
&*marginfi_group_loader.load()?,
Expand All @@ -65,15 +95,19 @@ pub fn lending_account_deposit<'info>(
&mut marginfi_account.lending_account,
)?;

bank_account.deposit(I80F48::from_num(amount))?;
bank_account.deposit(I80F48::from_num(deposit_amount))?;

let amount_pre_fee = maybe_bank_mint
.as_ref()
.map(|mint| {
utils::calculate_pre_fee_spl_deposit_amount(mint.to_account_info(), amount, clock.epoch)
utils::calculate_pre_fee_spl_deposit_amount(
mint.to_account_info(),
deposit_amount,
clock.epoch,
)
})
.transpose()?
.unwrap_or(amount);
.unwrap_or(deposit_amount);

bank_account.deposit_spl_transfer(
amount_pre_fee,
Expand All @@ -94,7 +128,7 @@ pub fn lending_account_deposit<'info>(
},
bank: bank_loader.key(),
mint: bank.mint,
amount,
amount: deposit_amount,
});

Ok(())
Expand Down
3 changes: 2 additions & 1 deletion programs/marginfi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ pub mod marginfi {
pub fn lending_account_deposit<'info>(
ctx: Context<'_, '_, 'info, 'info, LendingAccountDeposit<'info>>,
amount: u64,
deposit_up_to_limit: Option<bool>,
) -> MarginfiResult {
marginfi_account::lending_account_deposit(ctx, amount)
marginfi_account::lending_account_deposit(ctx, amount, deposit_up_to_limit)
}

pub fn lending_account_repay<'info>(
Expand Down
Loading
Loading