diff --git a/programs/stablecoin/src/generate_debt.rs b/programs/stablecoin/src/generate_debt.rs index 5bac576..7ecb163 100644 --- a/programs/stablecoin/src/generate_debt.rs +++ b/programs/stablecoin/src/generate_debt.rs @@ -16,7 +16,7 @@ use crate::shared::{ /// Mints stablecoin debt against an existing position. /// /// # Panics -/// Panics if the position is not authorized, the oracle is stale, or the post-mint position would +/// Panics if the owner is not authorized, the oracle is stale, or the post-mint position would /// be undercollateralized. #[expect( clippy::too_many_arguments, diff --git a/programs/stablecoin/src/shared.rs b/programs/stablecoin/src/shared.rs index 28bf4e2..ea4a828 100644 --- a/programs/stablecoin/src/shared.rs +++ b/programs/stablecoin/src/shared.rs @@ -7,7 +7,7 @@ use nssa_core::{ use stablecoin_core::{ compute_protocol_parameters_pda, compute_redemption_price_state_pda, compute_stability_fee_accumulator_pda, current_accumulated_rate, ProtocolParameters, - RedemptionPriceState, StabilityFeeAccumulator, + RedemptionPriceState, StabilityFeeAccumulator, MAXIMUM_COMPOUNDING_WINDOW_MILLISECONDS, }; pub(crate) fn read_clock_timestamp(clock: &AccountWithMetadata) -> u64 { @@ -84,9 +84,17 @@ pub(crate) fn accrue_stability_fee_state( params: &ProtocolParameters, now: u64, ) -> StabilityFeeAccumulator { + let elapsed = now + .saturating_sub(accumulator.last_accrued_at) + .min(MAXIMUM_COMPOUNDING_WINDOW_MILLISECONDS); + let last_accrued_at = accumulator + .last_accrued_at + .checked_add(elapsed) + .expect("Clamped elapsed timestamp cannot overflow"); + StabilityFeeAccumulator { accumulated_rate_at_last_accrual: current_accumulated_rate(accumulator, params, now), - last_accrued_at: now, + last_accrued_at, } } diff --git a/programs/stablecoin/src/tests.rs b/programs/stablecoin/src/tests.rs index ff075cd..ecea7b4 100644 --- a/programs/stablecoin/src/tests.rs +++ b/programs/stablecoin/src/tests.rs @@ -685,7 +685,7 @@ fn accrue_stability_fee_clamps_elapsed_window() { ); assert_eq!( updated.last_accrued_at, - MAXIMUM_COMPOUNDING_WINDOW_MILLISECONDS + 1 + MAXIMUM_COMPOUNDING_WINDOW_MILLISECONDS ); }