From 6cb86ed2b72152b17c55edb2c8a02d8f50a715a0 Mon Sep 17 00:00:00 2001 From: J Date: Thu, 23 Nov 2023 16:04:48 +0100 Subject: [PATCH 1/4] feat: lending pool add bank lite --- .../marginfi_account/initialize.rs | 2 +- .../instructions/marginfi_group/add_pool.rs | 61 ++++++++++++++++++- .../instructions/marginfi_group/initialize.rs | 2 +- programs/marginfi/src/lib.rs | 14 ++++- programs/marginfi/src/state/marginfi_group.rs | 16 +++++ programs/marginfi/tests/marginfi_group.rs | 21 +++++++ test-utils/src/marginfi_group.rs | 51 ++++++++++++++++ 7 files changed, 162 insertions(+), 5 deletions(-) diff --git a/programs/marginfi/src/instructions/marginfi_account/initialize.rs b/programs/marginfi/src/instructions/marginfi_account/initialize.rs index 20b5bfd47..4cabeb862 100644 --- a/programs/marginfi/src/instructions/marginfi_account/initialize.rs +++ b/programs/marginfi/src/instructions/marginfi_account/initialize.rs @@ -6,7 +6,7 @@ use crate::{ use anchor_lang::prelude::*; use solana_program::sysvar::Sysvar; -pub fn initialize(ctx: Context) -> MarginfiResult { +pub fn initialize_account(ctx: Context) -> MarginfiResult { let MarginfiAccountInitialize { authority, marginfi_group, diff --git a/programs/marginfi/src/instructions/marginfi_group/add_pool.rs b/programs/marginfi/src/instructions/marginfi_group/add_pool.rs index e64b4df5b..82e8fed1c 100644 --- a/programs/marginfi/src/instructions/marginfi_group/add_pool.rs +++ b/programs/marginfi/src/instructions/marginfi_group/add_pool.rs @@ -4,7 +4,10 @@ use crate::{ INSURANCE_VAULT_SEED, LIQUIDITY_VAULT_AUTHORITY_SEED, LIQUIDITY_VAULT_SEED, }, events::{GroupEventHeader, LendingPoolBankCreateEvent}, - state::marginfi_group::{Bank, BankConfig, MarginfiGroup}, + state::{ + marginfi_group::{Bank, BankConfig, MarginfiGroup}, + price::OracleSetup, + }, MarginfiResult, }; use anchor_lang::prelude::*; @@ -162,3 +165,59 @@ pub struct LendingPoolAddBank<'info> { pub token_program: Program<'info, Token>, pub system_program: Program<'info, System>, } + +/// Adds a bank with a default bank config providing just the oracle setup +pub fn lending_pool_add_bank_lite( + ctx: Context, + oracle_setup: OracleSetup, + oracle_keys: Vec, +) -> MarginfiResult { + let LendingPoolAddBank { + bank_mint, + liquidity_vault, + insurance_vault, + fee_vault, + bank: bank_loader, + .. + } = ctx.accounts; + + let mut bank = bank_loader.load_init()?; + + let liquidity_vault_bump = *ctx.bumps.get("liquidity_vault").unwrap(); + let liquidity_vault_authority_bump = *ctx.bumps.get("liquidity_vault_authority").unwrap(); + let insurance_vault_bump = *ctx.bumps.get("insurance_vault").unwrap(); + let insurance_vault_authority_bump = *ctx.bumps.get("insurance_vault_authority").unwrap(); + let fee_vault_bump = *ctx.bumps.get("fee_vault").unwrap(); + let fee_vault_authority_bump = *ctx.bumps.get("fee_vault_authority").unwrap(); + + *bank = Bank::new( + ctx.accounts.marginfi_group.key(), + BankConfig::new_with_oracle_config(oracle_setup, oracle_keys), + bank_mint.key(), + bank_mint.decimals, + liquidity_vault.key(), + insurance_vault.key(), + fee_vault.key(), + Clock::get().unwrap().unix_timestamp, + liquidity_vault_bump, + liquidity_vault_authority_bump, + insurance_vault_bump, + insurance_vault_authority_bump, + fee_vault_bump, + fee_vault_authority_bump, + ); + + bank.config.validate()?; + bank.config.validate_oracle_setup(ctx.remaining_accounts)?; + + emit!(LendingPoolBankCreateEvent { + header: GroupEventHeader { + marginfi_group: ctx.accounts.marginfi_group.key(), + signer: Some(*ctx.accounts.admin.key) + }, + bank: bank_loader.key(), + mint: bank_mint.key(), + }); + + Ok(()) +} diff --git a/programs/marginfi/src/instructions/marginfi_group/initialize.rs b/programs/marginfi/src/instructions/marginfi_group/initialize.rs index bc7779d94..2399e3ff7 100644 --- a/programs/marginfi/src/instructions/marginfi_group/initialize.rs +++ b/programs/marginfi/src/instructions/marginfi_group/initialize.rs @@ -2,7 +2,7 @@ use crate::events::{GroupEventHeader, MarginfiGroupCreateEvent}; use crate::{state::marginfi_group::MarginfiGroup, MarginfiResult}; use anchor_lang::prelude::*; -pub fn initialize(ctx: Context) -> MarginfiResult { +pub fn initialize_group(ctx: Context) -> MarginfiResult { let marginfi_group = &mut ctx.accounts.marginfi_group.load_init()?; marginfi_group.set_initial_configuration(ctx.accounts.admin.key()); diff --git a/programs/marginfi/src/lib.rs b/programs/marginfi/src/lib.rs index 5bc1fc887..0e3698537 100644 --- a/programs/marginfi/src/lib.rs +++ b/programs/marginfi/src/lib.rs @@ -7,6 +7,7 @@ pub mod prelude; pub mod state; pub mod utils; +use crate::state::price::OracleSetup; use anchor_lang::prelude::*; use instructions::*; use prelude::*; @@ -24,10 +25,11 @@ cfg_if::cfg_if! { #[program] pub mod marginfi { + use super::*; pub fn marginfi_group_initialize(ctx: Context) -> MarginfiResult { - marginfi_group::initialize(ctx) + marginfi_group::initialize_group(ctx) } pub fn marginfi_group_configure( @@ -44,6 +46,14 @@ pub mod marginfi { marginfi_group::lending_pool_add_bank(ctx, bank_config) } + pub fn lending_pool_add_bank_lite( + ctx: Context, + oracle_setup: OracleSetup, + oracle_keys: Vec, + ) -> MarginfiResult { + marginfi_group::lending_pool_add_bank_lite(ctx, oracle_setup, oracle_keys) + } + pub fn lending_pool_configure_bank( ctx: Context, bank_config_opt: BankConfigOpt, @@ -85,7 +95,7 @@ pub mod marginfi { /// Initialize a marginfi account for a given group pub fn marginfi_account_initialize(ctx: Context) -> MarginfiResult { - marginfi_account::initialize(ctx) + marginfi_account::initialize_account(ctx) } pub fn lending_account_deposit( diff --git a/programs/marginfi/src/state/marginfi_group.rs b/programs/marginfi/src/state/marginfi_group.rs index b08f69451..0c8c144a6 100644 --- a/programs/marginfi/src/state/marginfi_group.rs +++ b/programs/marginfi/src/state/marginfi_group.rs @@ -866,6 +866,22 @@ impl BankConfig { Ok(()) } + pub fn new_with_oracle_config(oracle_setup: OracleSetup, oracle_keys: Vec) -> Self { + assert!(oracle_keys.len() <= MAX_ORACLE_KEYS); + + let mut oracle_keys = [Pubkey::default(); 5]; + + for (i, key) in oracle_keys.into_iter().enumerate() { + oracle_keys[i] = key; + } + + Self { + oracle_setup, + oracle_keys, + ..Default::default() + } + } + #[inline] pub fn is_deposit_limit_active(&self) -> bool { self.deposit_limit != u64::MAX diff --git a/programs/marginfi/tests/marginfi_group.rs b/programs/marginfi/tests/marginfi_group.rs index f40c9f803..992f62c12 100644 --- a/programs/marginfi/tests/marginfi_group.rs +++ b/programs/marginfi/tests/marginfi_group.rs @@ -181,6 +181,27 @@ async fn marginfi_group_add_bank_success() -> anyhow::Result<()> { Ok(()) } +#[tokio::test] +async fn marginfi_group_add_bank_lite_success() -> anyhow::Result<()> { + // Setup test executor with non-admin payer + let test_f = TestFixture::new(None).await; + + let bank_asset_mint_fixture = MintFixture::new(test_f.context.clone(), None, None).await; + + let res = test_f + .marginfi_group + .try_lending_pool_add_bank_lite(&bank_asset_mint_fixture, *DEFAULT_USDC_TEST_BANK_CONFIG) + .await; + assert!(res.is_ok()); + + // Check bank is active + let bank = res.unwrap(); + let bank = test_f.try_load(&bank.key).await?; + assert!(bank.is_some()); + + Ok(()) +} + #[tokio::test] async fn marginfi_group_add_bank_failure_fake_pyth_feed() -> anyhow::Result<()> { // Setup test executor with non-admin payer diff --git a/test-utils/src/marginfi_group.rs b/test-utils/src/marginfi_group.rs index 646d37143..d226b4113 100644 --- a/test-utils/src/marginfi_group.rs +++ b/test-utils/src/marginfi_group.rs @@ -118,6 +118,57 @@ impl MarginfiGroupFixture { Ok(bank_fixture) } + pub async fn try_lending_pool_add_bank_lite( + &self, + bank_asset_mint_fixture: &MintFixture, + bank_config: BankConfig, + ) -> Result { + let bank_key = Keypair::new(); + let bank_mint = bank_asset_mint_fixture.key; + let bank_fixture = + BankFixture::new(self.ctx.clone(), bank_key.pubkey(), bank_asset_mint_fixture); + + let mut accounts = marginfi::accounts::LendingPoolAddBank { + marginfi_group: self.key, + admin: self.ctx.borrow().payer.pubkey(), + bank_mint, + bank: bank_key.pubkey(), + liquidity_vault_authority: bank_fixture.get_vault_authority(BankVaultType::Liquidity).0, + liquidity_vault: bank_fixture.get_vault(BankVaultType::Liquidity).0, + insurance_vault_authority: bank_fixture.get_vault_authority(BankVaultType::Insurance).0, + insurance_vault: bank_fixture.get_vault(BankVaultType::Insurance).0, + fee_vault_authority: bank_fixture.get_vault_authority(BankVaultType::Fee).0, + fee_vault: bank_fixture.get_vault(BankVaultType::Fee).0, + rent: sysvar::rent::id(), + token_program: token::ID, + system_program: system_program::id(), + } + .to_account_metas(Some(true)); + + accounts.push(AccountMeta::new_readonly(bank_config.oracle_keys[0], false)); + + let ix = Instruction { + program_id: marginfi::id(), + accounts, + data: marginfi::instruction::LendingPoolAddBankLite { oracle_setup: bank_config.oracle_setup, oracle_keys: vec![bank_config.oracle_keys[0]]}.data(), + }; + + let tx = Transaction::new_signed_with_payer( + &[ix], + Some(&self.ctx.borrow().payer.pubkey().clone()), + &[&self.ctx.borrow().payer, &bank_key], + self.ctx.borrow().last_blockhash, + ); + + self.ctx + .borrow_mut() + .banks_client + .process_transaction(tx) + .await?; + + Ok(bank_fixture) + } + pub fn make_lending_pool_configure_bank_ix( &self, bank: &BankFixture, From 25615a2ee096e4f9343d449fd95ec46fe4dc60dc Mon Sep 17 00:00:00 2001 From: J Date: Thu, 23 Nov 2023 16:07:06 +0100 Subject: [PATCH 2/4] fix: fmt --- test-utils/src/marginfi_group.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test-utils/src/marginfi_group.rs b/test-utils/src/marginfi_group.rs index d226b4113..bc9968048 100644 --- a/test-utils/src/marginfi_group.rs +++ b/test-utils/src/marginfi_group.rs @@ -150,7 +150,11 @@ impl MarginfiGroupFixture { let ix = Instruction { program_id: marginfi::id(), accounts, - data: marginfi::instruction::LendingPoolAddBankLite { oracle_setup: bank_config.oracle_setup, oracle_keys: vec![bank_config.oracle_keys[0]]}.data(), + data: marginfi::instruction::LendingPoolAddBankLite { + oracle_setup: bank_config.oracle_setup, + oracle_keys: vec![bank_config.oracle_keys[0]], + } + .data(), }; let tx = Transaction::new_signed_with_payer( From dc64339d2812f23b62b8a80df904d2a36be5ef76 Mon Sep 17 00:00:00 2001 From: J Date: Thu, 23 Nov 2023 20:13:01 +0100 Subject: [PATCH 3/4] fix: compact add bank ix --- clients/rust/marginfi-cli/src/entrypoint.rs | 12 +- .../rust/marginfi-cli/src/processor/mod.rs | 13 +- .../instructions/marginfi_group/add_pool.rs | 63 +-------- programs/marginfi/src/lib.rs | 16 +-- programs/marginfi/src/state/marginfi_group.rs | 126 ++++++++++++++++++ programs/marginfi/tests/marginfi_group.rs | 21 --- test-utils/src/marginfi_group.rs | 56 +------- 7 files changed, 149 insertions(+), 158 deletions(-) diff --git a/clients/rust/marginfi-cli/src/entrypoint.rs b/clients/rust/marginfi-cli/src/entrypoint.rs index 703a711f4..7f03230d7 100644 --- a/clients/rust/marginfi-cli/src/entrypoint.rs +++ b/clients/rust/marginfi-cli/src/entrypoint.rs @@ -98,9 +98,9 @@ pub enum GroupCommand { #[clap(long)] liability_weight_maint: f64, #[clap(long)] - deposit_limit: u64, + deposit_limit_ui: u64, #[clap(long)] - borrow_limit: u64, + borrow_limit_ui: u64, #[clap(long)] pyth_oracle: Pubkey, #[clap(long)] @@ -473,8 +473,8 @@ fn group(subcmd: GroupCommand, global_options: &GlobalOptions) -> Result<()> { insurance_ir_fee, protocol_fixed_fee_apr, protocol_ir_fee, - deposit_limit, - borrow_limit, + deposit_limit_ui, + borrow_limit_ui, risk_tier, oracle_type, } => processor::group_add_bank( @@ -487,8 +487,8 @@ fn group(subcmd: GroupCommand, global_options: &GlobalOptions) -> Result<()> { asset_weight_maint, liability_weight_init, liability_weight_maint, - deposit_limit, - borrow_limit, + deposit_limit_ui, + borrow_limit_ui, optimal_utilization_rate, plateau_interest_rate, max_interest_rate, diff --git a/clients/rust/marginfi-cli/src/processor/mod.rs b/clients/rust/marginfi-cli/src/processor/mod.rs index f82c34e0b..bd762b4cc 100644 --- a/clients/rust/marginfi-cli/src/processor/mod.rs +++ b/clients/rust/marginfi-cli/src/processor/mod.rs @@ -312,8 +312,8 @@ pub fn group_add_bank( asset_weight_maint: f64, liability_weight_init: f64, liability_weight_maint: f64, - deposit_limit: u64, - borrow_limit: u64, + deposit_limit_ui: u64, + borrow_limit_ui: u64, optimal_utilization_rate: f64, plateau_interest_rate: f64, max_interest_rate: f64, @@ -342,6 +342,12 @@ pub fn group_add_bank( let protocol_fixed_fee_apr: WrappedI80F48 = I80F48::from_num(protocol_fixed_fee_apr).into(); let protocol_ir_fee: WrappedI80F48 = I80F48::from_num(protocol_ir_fee).into(); + let mint_account = rpc_client.get_account(&bank_mint)?; + let mint = spl_token::state::Mint::unpack(&mint_account.data)?; + + let deposit_limit = deposit_limit_ui * 10_u64.pow(mint.decimals as u32); + let borrow_limit = borrow_limit_ui * 10_u64.pow(mint.decimals as u32); + let interest_rate_config = InterestRateConfig { optimal_utilization_rate, plateau_interest_rate, @@ -425,7 +431,8 @@ pub fn group_add_bank( oracle_keys: create_oracle_key_array(oracle_key), risk_tier: risk_tier.into(), ..BankConfig::default() - }, + } + .into(), }) .instructions()?; diff --git a/programs/marginfi/src/instructions/marginfi_group/add_pool.rs b/programs/marginfi/src/instructions/marginfi_group/add_pool.rs index 82e8fed1c..5d88a374c 100644 --- a/programs/marginfi/src/instructions/marginfi_group/add_pool.rs +++ b/programs/marginfi/src/instructions/marginfi_group/add_pool.rs @@ -4,10 +4,7 @@ use crate::{ INSURANCE_VAULT_SEED, LIQUIDITY_VAULT_AUTHORITY_SEED, LIQUIDITY_VAULT_SEED, }, events::{GroupEventHeader, LendingPoolBankCreateEvent}, - state::{ - marginfi_group::{Bank, BankConfig, MarginfiGroup}, - price::OracleSetup, - }, + state::marginfi_group::{Bank, BankConfig, BankConfigCompact, MarginfiGroup}, MarginfiResult, }; use anchor_lang::prelude::*; @@ -73,7 +70,7 @@ pub fn lending_pool_add_bank( } #[derive(Accounts)] -#[instruction(bank_config: BankConfig)] +#[instruction(bank_config: BankConfigCompact)] pub struct LendingPoolAddBank<'info> { pub marginfi_group: AccountLoader<'info, MarginfiGroup>, @@ -165,59 +162,3 @@ pub struct LendingPoolAddBank<'info> { pub token_program: Program<'info, Token>, pub system_program: Program<'info, System>, } - -/// Adds a bank with a default bank config providing just the oracle setup -pub fn lending_pool_add_bank_lite( - ctx: Context, - oracle_setup: OracleSetup, - oracle_keys: Vec, -) -> MarginfiResult { - let LendingPoolAddBank { - bank_mint, - liquidity_vault, - insurance_vault, - fee_vault, - bank: bank_loader, - .. - } = ctx.accounts; - - let mut bank = bank_loader.load_init()?; - - let liquidity_vault_bump = *ctx.bumps.get("liquidity_vault").unwrap(); - let liquidity_vault_authority_bump = *ctx.bumps.get("liquidity_vault_authority").unwrap(); - let insurance_vault_bump = *ctx.bumps.get("insurance_vault").unwrap(); - let insurance_vault_authority_bump = *ctx.bumps.get("insurance_vault_authority").unwrap(); - let fee_vault_bump = *ctx.bumps.get("fee_vault").unwrap(); - let fee_vault_authority_bump = *ctx.bumps.get("fee_vault_authority").unwrap(); - - *bank = Bank::new( - ctx.accounts.marginfi_group.key(), - BankConfig::new_with_oracle_config(oracle_setup, oracle_keys), - bank_mint.key(), - bank_mint.decimals, - liquidity_vault.key(), - insurance_vault.key(), - fee_vault.key(), - Clock::get().unwrap().unix_timestamp, - liquidity_vault_bump, - liquidity_vault_authority_bump, - insurance_vault_bump, - insurance_vault_authority_bump, - fee_vault_bump, - fee_vault_authority_bump, - ); - - bank.config.validate()?; - bank.config.validate_oracle_setup(ctx.remaining_accounts)?; - - emit!(LendingPoolBankCreateEvent { - header: GroupEventHeader { - marginfi_group: ctx.accounts.marginfi_group.key(), - signer: Some(*ctx.accounts.admin.key) - }, - bank: bank_loader.key(), - mint: bank_mint.key(), - }); - - Ok(()) -} diff --git a/programs/marginfi/src/lib.rs b/programs/marginfi/src/lib.rs index 0e3698537..39cb36b85 100644 --- a/programs/marginfi/src/lib.rs +++ b/programs/marginfi/src/lib.rs @@ -7,11 +7,10 @@ pub mod prelude; pub mod state; pub mod utils; -use crate::state::price::OracleSetup; use anchor_lang::prelude::*; use instructions::*; use prelude::*; -use state::marginfi_group::{BankConfig, BankConfigOpt}; +use state::marginfi_group::{BankConfigCompact, BankConfigOpt}; cfg_if::cfg_if! { if #[cfg(feature = "mainnet-beta")] { @@ -25,7 +24,6 @@ cfg_if::cfg_if! { #[program] pub mod marginfi { - use super::*; pub fn marginfi_group_initialize(ctx: Context) -> MarginfiResult { @@ -41,17 +39,9 @@ pub mod marginfi { pub fn lending_pool_add_bank( ctx: Context, - bank_config: BankConfig, - ) -> MarginfiResult { - marginfi_group::lending_pool_add_bank(ctx, bank_config) - } - - pub fn lending_pool_add_bank_lite( - ctx: Context, - oracle_setup: OracleSetup, - oracle_keys: Vec, + bank_config: BankConfigCompact, ) -> MarginfiResult { - marginfi_group::lending_pool_add_bank_lite(ctx, oracle_setup, oracle_keys) + marginfi_group::lending_pool_add_bank(ctx, bank_config.into()) } pub fn lending_pool_configure_bank( diff --git a/programs/marginfi/src/state/marginfi_group.rs b/programs/marginfi/src/state/marginfi_group.rs index 0c8c144a6..783afbaec 100644 --- a/programs/marginfi/src/state/marginfi_group.rs +++ b/programs/marginfi/src/state/marginfi_group.rs @@ -72,6 +72,55 @@ pub fn load_pyth_price_feed(ai: &AccountInfo) -> MarginfiResult { Ok(price_feed) } +#[zero_copy] +#[repr(C)] +#[cfg_attr( + any(feature = "test", feature = "client"), + derive(PartialEq, Eq, TypeLayout) +)] +#[derive(Default, Debug, AnchorDeserialize, AnchorSerialize)] +pub struct InterestRateConfigCompact { + // Curve Params + pub optimal_utilization_rate: WrappedI80F48, + pub plateau_interest_rate: WrappedI80F48, + pub max_interest_rate: WrappedI80F48, + + // Fees + pub insurance_fee_fixed_apr: WrappedI80F48, + pub insurance_ir_fee: WrappedI80F48, + pub protocol_fixed_fee_apr: WrappedI80F48, + pub protocol_ir_fee: WrappedI80F48, +} + +impl From for InterestRateConfig { + fn from(ir_config: InterestRateConfigCompact) -> Self { + InterestRateConfig { + optimal_utilization_rate: ir_config.optimal_utilization_rate, + plateau_interest_rate: ir_config.plateau_interest_rate, + max_interest_rate: ir_config.max_interest_rate, + insurance_fee_fixed_apr: ir_config.insurance_fee_fixed_apr, + insurance_ir_fee: ir_config.insurance_ir_fee, + protocol_fixed_fee_apr: ir_config.protocol_fixed_fee_apr, + protocol_ir_fee: ir_config.protocol_ir_fee, + _padding: [0; 8], + } + } +} + +impl From for InterestRateConfigCompact { + fn from(ir_config: InterestRateConfig) -> Self { + InterestRateConfigCompact { + optimal_utilization_rate: ir_config.optimal_utilization_rate, + plateau_interest_rate: ir_config.plateau_interest_rate, + max_interest_rate: ir_config.max_interest_rate, + insurance_fee_fixed_apr: ir_config.insurance_fee_fixed_apr, + insurance_ir_fee: ir_config.insurance_ir_fee, + protocol_fixed_fee_apr: ir_config.protocol_fixed_fee_apr, + protocol_ir_fee: ir_config.protocol_ir_fee, + } + } +} + #[zero_copy] #[repr(C)] #[cfg_attr( @@ -760,6 +809,83 @@ pub enum RiskTier { Isolated, } +#[zero_copy] +#[repr(C)] +#[cfg_attr( + any(feature = "test", feature = "client"), + derive(PartialEq, Eq, TypeLayout) +)] +#[derive(AnchorDeserialize, AnchorSerialize, Debug)] +/// TODO: Convert weights to (u64, u64) to avoid precision loss (maybe?) +pub struct BankConfigCompact { + pub asset_weight_init: WrappedI80F48, + pub asset_weight_maint: WrappedI80F48, + + pub liability_weight_init: WrappedI80F48, + pub liability_weight_maint: WrappedI80F48, + + pub deposit_limit: u64, + + pub interest_rate_config: InterestRateConfigCompact, + pub operational_state: BankOperationalState, + + pub oracle_setup: OracleSetup, + pub oracle_keys: [Pubkey; MAX_ORACLE_KEYS], + + pub borrow_limit: u64, + + pub risk_tier: RiskTier, + + /// USD denominated limit for calculating asset value for initialization margin requirements. + /// Example, if total SOL deposits are equal to $1M and the limit it set to $500K, + /// then SOL assets will be discounted by 50%. + /// + /// In other words the max value of liabilities that can be backed by the asset is $500K. + /// This is useful for limiting the damage of orcale attacks. + /// + /// Value is UI USD value, for example value 100 -> $100 + pub total_asset_value_init_limit: u64, +} + +impl From for BankConfig { + fn from(config: BankConfigCompact) -> Self { + Self { + asset_weight_init: config.asset_weight_init, + asset_weight_maint: config.asset_weight_maint, + liability_weight_init: config.liability_weight_init, + liability_weight_maint: config.liability_weight_maint, + deposit_limit: config.deposit_limit, + interest_rate_config: config.interest_rate_config.into(), + operational_state: config.operational_state, + oracle_setup: config.oracle_setup, + oracle_keys: config.oracle_keys, + borrow_limit: config.borrow_limit, + risk_tier: config.risk_tier, + total_asset_value_init_limit: config.total_asset_value_init_limit, + _padding: [0; 5], + } + } +} + +impl From for BankConfigCompact { + fn from(config: BankConfig) -> Self { + Self { + asset_weight_init: config.asset_weight_init, + asset_weight_maint: config.asset_weight_maint, + liability_weight_init: config.liability_weight_init, + liability_weight_maint: config.liability_weight_maint, + deposit_limit: config.deposit_limit, + interest_rate_config: config.interest_rate_config.into(), + operational_state: config.operational_state, + oracle_setup: config.oracle_setup, + oracle_keys: config.oracle_keys, + borrow_limit: config.borrow_limit, + risk_tier: config.risk_tier, + total_asset_value_init_limit: config.total_asset_value_init_limit, + } + } +} + assert_struct_size!(BankConfig, 544); #[zero_copy] #[repr(C)] diff --git a/programs/marginfi/tests/marginfi_group.rs b/programs/marginfi/tests/marginfi_group.rs index 992f62c12..f40c9f803 100644 --- a/programs/marginfi/tests/marginfi_group.rs +++ b/programs/marginfi/tests/marginfi_group.rs @@ -181,27 +181,6 @@ async fn marginfi_group_add_bank_success() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] -async fn marginfi_group_add_bank_lite_success() -> anyhow::Result<()> { - // Setup test executor with non-admin payer - let test_f = TestFixture::new(None).await; - - let bank_asset_mint_fixture = MintFixture::new(test_f.context.clone(), None, None).await; - - let res = test_f - .marginfi_group - .try_lending_pool_add_bank_lite(&bank_asset_mint_fixture, *DEFAULT_USDC_TEST_BANK_CONFIG) - .await; - assert!(res.is_ok()); - - // Check bank is active - let bank = res.unwrap(); - let bank = test_f.try_load(&bank.key).await?; - assert!(bank.is_some()); - - Ok(()) -} - #[tokio::test] async fn marginfi_group_add_bank_failure_fake_pyth_feed() -> anyhow::Result<()> { // Setup test executor with non-admin payer diff --git a/test-utils/src/marginfi_group.rs b/test-utils/src/marginfi_group.rs index bc9968048..d44b9756c 100644 --- a/test-utils/src/marginfi_group.rs +++ b/test-utils/src/marginfi_group.rs @@ -99,60 +99,8 @@ impl MarginfiGroupFixture { let ix = Instruction { program_id: marginfi::id(), accounts, - data: marginfi::instruction::LendingPoolAddBank { bank_config }.data(), - }; - - let tx = Transaction::new_signed_with_payer( - &[ix], - Some(&self.ctx.borrow().payer.pubkey().clone()), - &[&self.ctx.borrow().payer, &bank_key], - self.ctx.borrow().last_blockhash, - ); - - self.ctx - .borrow_mut() - .banks_client - .process_transaction(tx) - .await?; - - Ok(bank_fixture) - } - - pub async fn try_lending_pool_add_bank_lite( - &self, - bank_asset_mint_fixture: &MintFixture, - bank_config: BankConfig, - ) -> Result { - let bank_key = Keypair::new(); - let bank_mint = bank_asset_mint_fixture.key; - let bank_fixture = - BankFixture::new(self.ctx.clone(), bank_key.pubkey(), bank_asset_mint_fixture); - - let mut accounts = marginfi::accounts::LendingPoolAddBank { - marginfi_group: self.key, - admin: self.ctx.borrow().payer.pubkey(), - bank_mint, - bank: bank_key.pubkey(), - liquidity_vault_authority: bank_fixture.get_vault_authority(BankVaultType::Liquidity).0, - liquidity_vault: bank_fixture.get_vault(BankVaultType::Liquidity).0, - insurance_vault_authority: bank_fixture.get_vault_authority(BankVaultType::Insurance).0, - insurance_vault: bank_fixture.get_vault(BankVaultType::Insurance).0, - fee_vault_authority: bank_fixture.get_vault_authority(BankVaultType::Fee).0, - fee_vault: bank_fixture.get_vault(BankVaultType::Fee).0, - rent: sysvar::rent::id(), - token_program: token::ID, - system_program: system_program::id(), - } - .to_account_metas(Some(true)); - - accounts.push(AccountMeta::new_readonly(bank_config.oracle_keys[0], false)); - - let ix = Instruction { - program_id: marginfi::id(), - accounts, - data: marginfi::instruction::LendingPoolAddBankLite { - oracle_setup: bank_config.oracle_setup, - oracle_keys: vec![bank_config.oracle_keys[0]], + data: marginfi::instruction::LendingPoolAddBank { + bank_config: bank_config.into(), } .data(), }; From 3f97c95d1401fb72eb84feb938829aba14bb0909 Mon Sep 17 00:00:00 2001 From: J Date: Thu, 23 Nov 2023 20:23:17 +0100 Subject: [PATCH 4/4] fix: remove new_from_oracle_config builder --- programs/marginfi/src/state/marginfi_group.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/programs/marginfi/src/state/marginfi_group.rs b/programs/marginfi/src/state/marginfi_group.rs index 783afbaec..64ef0f620 100644 --- a/programs/marginfi/src/state/marginfi_group.rs +++ b/programs/marginfi/src/state/marginfi_group.rs @@ -992,22 +992,6 @@ impl BankConfig { Ok(()) } - pub fn new_with_oracle_config(oracle_setup: OracleSetup, oracle_keys: Vec) -> Self { - assert!(oracle_keys.len() <= MAX_ORACLE_KEYS); - - let mut oracle_keys = [Pubkey::default(); 5]; - - for (i, key) in oracle_keys.into_iter().enumerate() { - oracle_keys[i] = key; - } - - Self { - oracle_setup, - oracle_keys, - ..Default::default() - } - } - #[inline] pub fn is_deposit_limit_active(&self) -> bool { self.deposit_limit != u64::MAX