collateral fees: fixes after devnet test (#880)

This commit is contained in:
Christian Kamm 2024-02-14 11:32:57 +01:00 committed by GitHub
parent 7a1be5a188
commit 3993a3fa66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 6 deletions

View File

@ -26,6 +26,7 @@ use prometheus::{register_histogram, Encoder, Histogram, IntCounter, Registry};
use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
signature::Signature,
};
use tokio::task::JoinHandle;
use tracing::*;
@ -507,12 +508,13 @@ async fn charge_collateral_fees_inner(
ix_to_send.push(ixs);
}
send_batched_log_errors_no_confirm(
let txsigs = send_batched_log_errors_no_confirm(
client.transaction_builder().await?,
&client.client,
&ix_to_send,
)
.await;
info!("charge collateral fees: {:?}", txsigs);
Ok(())
}
@ -522,7 +524,9 @@ async fn send_batched_log_errors_no_confirm(
mut tx_builder: TransactionBuilder,
client: &mango_v4_client::Client,
ixs_list: &[PreparedInstructions],
) {
) -> Vec<Signature> {
let mut txsigs = Vec::new();
let mut current_batch = PreparedInstructions::new();
for ixs in ixs_list {
let previous_batch = current_batch.clone();
@ -533,7 +537,7 @@ async fn send_batched_log_errors_no_confirm(
tx_builder.instructions = previous_batch.to_instructions();
match tx_builder.send(client).await {
Err(err) => error!("could not send transaction: {err:?}"),
_ => {}
Ok(txsig) => txsigs.push(txsig),
}
current_batch = ixs.clone();
@ -544,7 +548,9 @@ async fn send_batched_log_errors_no_confirm(
tx_builder.instructions = current_batch.to_instructions();
match tx_builder.send(client).await {
Err(err) => error!("could not send transaction: {err:?}"),
_ => {}
Ok(txsig) => txsigs.push(txsig),
}
}
txsigs
}

View File

@ -67,6 +67,11 @@ pub fn token_charge_collateral_fees(ctx: Context<TokenChargeCollateralFees>) ->
}
}
// If there's no assets or no liabs, we can't charge fees
if total_asset_health.is_zero() || total_liab_health.is_zero() {
return Ok(());
}
// Users only pay for assets that are actively used to cover their liabilities.
let asset_usage_scaling = (total_liab_health / total_asset_health)
.max(I80F48::ZERO)
@ -77,7 +82,7 @@ pub fn token_charge_collateral_fees(ctx: Context<TokenChargeCollateralFees>) ->
let token_position_count = account.active_token_positions().count();
for bank_ai in &ctx.remaining_accounts[0..token_position_count] {
let mut bank = bank_ai.load_mut::<Bank>()?;
if bank.collateral_fee_per_day <= 0.0 {
if bank.collateral_fee_per_day <= 0.0 || bank.maint_asset_weight.is_zero() {
continue;
}

View File

@ -1,3 +1,4 @@
#![allow(unused_assignments)]
use super::*;
#[tokio::test]
@ -44,6 +45,18 @@ async fn test_collateral_fees() -> Result<(), TransportError> {
)
.await;
let empty_account = create_funded_account(
&solana,
group,
owner,
2,
&context.users[1],
&mints[0..0],
0,
0,
)
.await;
let hour = 60 * 60;
send_tx(
@ -92,6 +105,32 @@ async fn test_collateral_fees() -> Result<(), TransportError> {
.await
.unwrap();
//
// TEST: It works on empty accounts
//
send_tx(
solana,
TokenChargeCollateralFeesInstruction {
account: empty_account,
},
)
.await
.unwrap();
let mut last_time = solana.clock_timestamp().await;
solana.set_clock_timestamp(last_time + 9 * hour).await;
// send it twice, because the first time will never charge anything
send_tx(
solana,
TokenChargeCollateralFeesInstruction {
account: empty_account,
},
)
.await
.unwrap();
last_time = solana.clock_timestamp().await;
//
// TEST: Without borrows, charging collateral fees has no effect
//
@ -99,7 +138,15 @@ async fn test_collateral_fees() -> Result<(), TransportError> {
send_tx(solana, TokenChargeCollateralFeesInstruction { account })
.await
.unwrap();
let mut last_time = solana.clock_timestamp().await;
last_time = solana.clock_timestamp().await;
solana.set_clock_timestamp(last_time + 9 * hour).await;
// send it twice, because the first time will never charge anything
send_tx(solana, TokenChargeCollateralFeesInstruction { account })
.await
.unwrap();
last_time = solana.clock_timestamp().await;
// no effect
assert_eq!(
account_position(solana, account, tokens[0].bank).await,