Skip to content

Commit

Permalink
Reconcile merge with main
Browse files Browse the repository at this point in the history
  • Loading branch information
jgur-psyops committed Dec 12, 2024
2 parents 989f21c + 244a3b3 commit 907fa7e
Show file tree
Hide file tree
Showing 25 changed files with 1,090 additions and 452 deletions.
3 changes: 3 additions & 0 deletions .github/actions/setup-common/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ runs:

- run: cargo install cargo-nextest --locked
shell: bash

- run: cargo nextest --version
shell: bash
5 changes: 3 additions & 2 deletions Anchor.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[toolchain]
anchor_version = "0.30.1"
solana_version = "1.18.11"
solana_version = "1.18.17"
# Getting "thread 'main' panicked at cli/src/lib.rs:545:18:"? Check your toolchain matches the above.

[features]
resolution = true
Expand All @@ -10,7 +11,7 @@ skip-lint = false
# liquidity_incentive_program = "Lip1111111111111111111111111111111111111111"
marginfi = "2jGhuVUuy3umdzByFx8sNWUAaf5vaeuDm78RDPEnhrMr"
mocks = "5XaaR94jBubdbrRrNW7DtRvZeWvLhSHkEGU3jHTEXV3C"
spl_single_pool = "SVSPxpvHdN29nkVg9rPapPNDddN5DipNLRUFhyjFThE" # cloned from solana-labs repo (see below)
spl_single_pool = "SVSPxpvHdN29nkVg9rPapPNDddN5DipNLRUFhyjFThE" # cloned from solana-labs repo (see below)

[programs.mainnet]
liquidity_incentive_program = "LipsxuAkFkwa4RKNzn51wAsW7Dedzt1RNHMkTkDEZUW"
Expand Down
73 changes: 72 additions & 1 deletion clients/rust/marginfi-cli/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,36 @@ pub enum GroupCommand {
#[clap(short = 't', long)]
existing_token_lookup_tables: Vec<Pubkey>,
},
InitFeeState {
#[clap(long)]
admin: Pubkey,
#[clap(long)]
fee_wallet: Pubkey,
#[clap(long)]
bank_init_flat_sol_fee: u32,
#[clap(long)]
program_fee_fixed: f64,
#[clap(long)]
program_fee_rate: f64,
},
EditFeeState {
#[clap(long)]
fee_wallet: Pubkey,
#[clap(long)]
bank_init_flat_sol_fee: u32,
#[clap(long)]
program_fee_fixed: f64,
#[clap(long)]
program_fee_rate: f64,
},
ConfigGroupFee {
#[clap(long)]
flag: u64,
},
PropagateFee {
#[clap(long)]
marginfi_group: Pubkey,
},
}

#[derive(Clone, Copy, Debug, Parser, ArgEnum)]
Expand Down Expand Up @@ -277,6 +307,11 @@ pub enum BankCommand {
help = "Permissionless bad debt settlement, if true the group admin is not required to settle bad debt"
)]
permissionless_bad_debt_settlement: Option<bool>,
#[clap(
long,
help = "If enabled, will prevent this Update ix from ever running against after this invokation"
)]
freeze_settings: Option<bool>,
},
InspectPriceOracle {
bank_pk: Pubkey,
Expand Down Expand Up @@ -312,6 +347,8 @@ pub enum BankCommand {
},
CollectFees {
bank: Pubkey,
#[clap(help = "The ATA for fee_state.global_fee_wallet and the bank's mint")]
fee_ata: Pubkey,
},
WithdrawFees {
bank: Pubkey,
Expand Down Expand Up @@ -638,6 +675,36 @@ fn group(subcmd: GroupCommand, global_options: &GlobalOptions) -> Result<()> {
&profile,
existing_token_lookup_tables,
),
GroupCommand::InitFeeState {
admin,
fee_wallet,
bank_init_flat_sol_fee,
program_fee_fixed,
program_fee_rate,
} => processor::initialize_fee_state(
config,
admin,
fee_wallet,
bank_init_flat_sol_fee,
program_fee_fixed,
program_fee_rate,
),
GroupCommand::EditFeeState {
fee_wallet,
bank_init_flat_sol_fee,
program_fee_fixed,
program_fee_rate,
} => processor::edit_fee_state(
config,
fee_wallet,
bank_init_flat_sol_fee,
program_fee_fixed,
program_fee_rate,
),
GroupCommand::ConfigGroupFee { flag } => processor::config_group_fee(config, profile, flag),
GroupCommand::PropagateFee { marginfi_group } => {
processor::propagate_fee(config, marginfi_group)
}
}
}

Expand Down Expand Up @@ -682,6 +749,7 @@ fn bank(subcmd: BankCommand, global_options: &GlobalOptions) -> Result<()> {
usd_init_limit,
oracle_max_age,
permissionless_bad_debt_settlement,
freeze_settings,
} => {
let bank = config
.mfi_program
Expand Down Expand Up @@ -732,6 +800,7 @@ fn bank(subcmd: BankCommand, global_options: &GlobalOptions) -> Result<()> {
total_asset_value_init_limit: usd_init_limit,
oracle_max_age,
permissionless_bad_debt_settlement,
freeze_settings,
},
)
}
Expand Down Expand Up @@ -768,7 +837,9 @@ fn bank(subcmd: BankCommand, global_options: &GlobalOptions) -> Result<()> {
BankCommand::SettleAllEmissions { bank } => {
processor::emissions::claim_all_emissions_for_bank(&config, &profile, bank)
}
BankCommand::CollectFees { bank } => processor::admin::process_collect_fees(config, bank),
BankCommand::CollectFees { bank, fee_ata } => {
processor::admin::process_collect_fees(config, bank, fee_ata)
}
BankCommand::WithdrawFees {
bank,
amount,
Expand Down
4 changes: 2 additions & 2 deletions clients/rust/marginfi-cli/src/processor/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use solana_sdk::{
instruction::Instruction, message::Message, pubkey::Pubkey, transaction::Transaction,
};

pub fn process_collect_fees(config: Config, bank_pk: Pubkey) -> Result<()> {
pub fn process_collect_fees(config: Config, bank_pk: Pubkey, fee_ata: Pubkey) -> Result<()> {
let bank = config.mfi_program.account::<Bank>(bank_pk)?;
let rpc_client = config.mfi_program.rpc();

Expand All @@ -33,7 +33,7 @@ pub fn process_collect_fees(config: Config, bank_pk: Pubkey) -> Result<()> {
liquidity_vault: bank.liquidity_vault,
insurance_vault: bank.insurance_vault,
fee_state: find_fee_state_pda(&marginfi::id()).0,
fee_ata: find_fee_state_pda(&marginfi::id()).0, // TODO
fee_ata,
}
.to_account_metas(Some(true)),
data: marginfi::instruction::LendingPoolCollectBankFees {}.data(),
Expand Down
164 changes: 164 additions & 0 deletions clients/rust/marginfi-cli/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,170 @@ pub fn process_set_user_flag(
Ok(())
}

pub fn initialize_fee_state(
config: Config,
admin: Pubkey,
fee_wallet: Pubkey,
bank_init_flat_sol_fee: u32,
program_fee_fixed: f64,
program_fee_rate: f64,
) -> Result<()> {
let program_fee_fixed: WrappedI80F48 = I80F48::from_num(program_fee_fixed).into();
let program_fee_rate: WrappedI80F48 = I80F48::from_num(program_fee_rate).into();

let rpc_client = config.mfi_program.rpc();

let fee_state_pubkey = find_fee_state_pda(&config.program_id).0;

let initialize_fee_state_ixs_builder = config.mfi_program.request();

let initialize_fee_state_ixs = initialize_fee_state_ixs_builder
.accounts(marginfi::accounts::InitFeeState {
payer: config.authority(),
fee_state: fee_state_pubkey,
rent: sysvar::rent::id(),
system_program: system_program::id(),
})
.args(marginfi::instruction::InitGlobalFeeState {
admin,
fee_wallet,
bank_init_flat_sol_fee,
program_fee_fixed,
program_fee_rate,
})
.instructions()?;

let recent_blockhash = rpc_client.get_latest_blockhash().unwrap();
let message = Message::new(&initialize_fee_state_ixs, Some(&config.authority()));
let mut transaction = Transaction::new_unsigned(message);
transaction.partial_sign(&config.get_signers(false), recent_blockhash);

match process_transaction(&transaction, &rpc_client, config.get_tx_mode()) {
Ok(sig) => println!("Fee state initialized (sig: {})", sig),
Err(err) => {
println!("Error during fee state initialization:\n{:#?}", err);
return Err(anyhow!("Error during fee state initialization"));
}
};

Ok(())
}

pub fn edit_fee_state(
config: Config,
fee_wallet: Pubkey,
bank_init_flat_sol_fee: u32,
program_fee_fixed: f64,
program_fee_rate: f64,
) -> Result<()> {
let program_fee_fixed: WrappedI80F48 = I80F48::from_num(program_fee_fixed).into();
let program_fee_rate: WrappedI80F48 = I80F48::from_num(program_fee_rate).into();

let rpc_client = config.mfi_program.rpc();

let fee_state_pubkey = find_fee_state_pda(&config.program_id).0;

let edit_fee_state_ixs_builder = config.mfi_program.request();

let edit_fee_state_ixs = edit_fee_state_ixs_builder
.accounts(marginfi::accounts::EditFeeState {
global_fee_admin: config.authority(),
fee_state: fee_state_pubkey,
})
.args(marginfi::instruction::EditGlobalFeeState {
fee_wallet,
bank_init_flat_sol_fee,
program_fee_fixed,
program_fee_rate,
})
.instructions()?;

let recent_blockhash = rpc_client.get_latest_blockhash().unwrap();
let message = Message::new(&edit_fee_state_ixs, Some(&config.authority()));
let mut transaction = Transaction::new_unsigned(message);
transaction.partial_sign(&config.get_signers(false), recent_blockhash);

match process_transaction(&transaction, &rpc_client, config.get_tx_mode()) {
Ok(sig) => println!("Fee state edited (sig: {})", sig),
Err(err) => {
println!("Error during fee state edit:\n{:#?}", err);
return Err(anyhow!("Error during fee state edit"));
}
};

Ok(())
}

pub fn config_group_fee(config: Config, profile: Profile, flag: u64) -> Result<()> {
let rpc_client = config.mfi_program.rpc();
let marginfi_group_pubkey = profile.marginfi_group.ok_or_else(|| {
anyhow!(
"Marginfi group does not exist for profile [{}]",
profile.name
)
})?;

let fee_state_pubkey = find_fee_state_pda(&profile.program_id.unwrap()).0;

let config_group_fee_ixs_builder = config.mfi_program.request();

let config_group_fee_ixs = config_group_fee_ixs_builder
.accounts(marginfi::accounts::ConfigGroupFee {
marginfi_group: marginfi_group_pubkey,
global_fee_admin: config.authority(),
fee_state: fee_state_pubkey,
})
.args(marginfi::instruction::ConfigGroupFee { flag })
.instructions()?;

let recent_blockhash = rpc_client.get_latest_blockhash().unwrap();
let message = Message::new(&config_group_fee_ixs, Some(&config.authority()));
let mut transaction = Transaction::new_unsigned(message);
transaction.partial_sign(&config.get_signers(false), recent_blockhash);

match process_transaction(&transaction, &rpc_client, config.get_tx_mode()) {
Ok(sig) => println!("Config group fee updated (sig: {})", sig),
Err(err) => {
println!("Error during config group fee update:\n{:#?}", err);
return Err(anyhow!("Error during config group fee update"));
}
};

Ok(())
}

/// Note: doing this one group at a time is tedious, consider running the script instead.
pub fn propagate_fee(config: Config, marginfi_group: Pubkey) -> Result<()> {
let rpc_client = config.mfi_program.rpc();

let fee_state_pubkey = find_fee_state_pda(&config.program_id).0;

let propagate_fee_ixs_builder = config.mfi_program.request();

let propagate_fee_ixs = propagate_fee_ixs_builder
.accounts(marginfi::accounts::PropagateFee {
fee_state: fee_state_pubkey,
marginfi_group,
})
.args(marginfi::instruction::PropagateFeeState {})
.instructions()?;

let recent_blockhash = rpc_client.get_latest_blockhash().unwrap();
let message = Message::new(&propagate_fee_ixs, None);
let mut transaction = Transaction::new_unsigned(message);
transaction.partial_sign(&config.get_signers(false), recent_blockhash);

match process_transaction(&transaction, &rpc_client, config.get_tx_mode()) {
Ok(sig) => println!("Fee propagated (sig: {})", sig),
Err(err) => {
println!("Error during fee propagation:\n{:#?}", err);
return Err(anyhow!("Error during fee propagation"));
}
};

Ok(())
}

// --------------------------------------------------------------------------------------------------------------------
// bank
// --------------------------------------------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"@solana/spl-token": "^0.4.8",
"@solana/web3.js": "^1.95.2",
"@solana/spl-single-pool-classic": "^1.0.2",
"@mrgnlabs/mrgn-common": "^1.7.0",
"@mrgnlabs/marginfi-client-v2": "^3.1.0",
"@mrgnlabs/mrgn-common": "^1.8.0",
"@mrgnlabs/marginfi-client-v2": "^4.0.0",
"mocha": "^10.2.0",
"ts-mocha": "^10.0.0",
"bignumber.js": "^9.1.2"
Expand Down
3 changes: 2 additions & 1 deletion programs/marginfi/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ pub const ZERO_AMOUNT_THRESHOLD: I80F48 = I80F48!(0.0001);
pub const EMISSIONS_FLAG_BORROW_ACTIVE: u64 = 1 << 0;
pub const EMISSIONS_FLAG_LENDING_ACTIVE: u64 = 1 << 1;
pub const PERMISSIONLESS_BAD_DEBT_SETTLEMENT_FLAG: u64 = 1 << 2;
pub const FREEZE_SETTINGS: u64 = 1 << 3;

pub(crate) const EMISSION_FLAGS: u64 = EMISSIONS_FLAG_BORROW_ACTIVE | EMISSIONS_FLAG_LENDING_ACTIVE;
pub(crate) const GROUP_FLAGS: u64 = PERMISSIONLESS_BAD_DEBT_SETTLEMENT_FLAG;
pub(crate) const GROUP_FLAGS: u64 = PERMISSIONLESS_BAD_DEBT_SETTLEMENT_FLAG | FREEZE_SETTINGS;

/// Cutoff timestamp for balance last_update used in accounting collected emissions.
/// Any balance updates before this timestamp are ignored, and current_timestamp is used instead.
Expand Down
2 changes: 2 additions & 0 deletions programs/marginfi/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ pub enum MarginfiError {
InvalidFeeAta,
#[msg("Use add pool permissionless instead")] // 6050
AddedStakedPoolManually,
#[msg("Bank settings are frozen and cannot be updated")] // 6051
BankSettingsFrozen,
}

impl From<MarginfiError> for ProgramError {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::constants::{EMISSIONS_AUTH_SEED, EMISSIONS_TOKEN_ACCOUNT_SEED};
use crate::constants::{EMISSIONS_AUTH_SEED, EMISSIONS_TOKEN_ACCOUNT_SEED, FREEZE_SETTINGS};
use crate::events::{GroupEventHeader, LendingPoolBankConfigureEvent};
use crate::prelude::MarginfiError;
use crate::{check, math_error, utils};
Expand All @@ -17,6 +17,11 @@ pub fn lending_pool_configure_bank(
) -> MarginfiResult {
let mut bank = ctx.accounts.bank.load_mut()?;

check!(
!bank.get_flag(FREEZE_SETTINGS),
MarginfiError::BankSettingsFrozen
);

bank.configure(&bank_config)?;

if bank_config.oracle.is_some() {
Expand Down
Loading

0 comments on commit 907fa7e

Please sign in to comment.