Skip to main content

Rate Model

The RateModel account stores the interest rate model parameters for calculating dynamic interest rates based on utilization. The model is fully parameterizable, allowing customization of rate behavior for different pool types.

Account Structure

#[account]
pub struct RateModel {
    /// exp_rate: NAD/millisecond (k_real = exp_rate / NAD)
    /// Derived from half_life_ms: exp_rate = ln(2) / half_life_ms
    pub exp_rate: u64,
    /// Utilization band edges (NAD-scaled: 0..NAD)
    pub target_util_start: u64,
    pub target_util_end: u64,
    /// Rate adjustment half-life in milliseconds
    pub half_life_ms: u64,
    /// Minimum interest rate floor (NAD-scaled)
    pub min_rate: u64,
    /// Maximum interest rate ceiling (NAD-scaled, 0 = no cap)
    pub max_rate: u64,
    /// Initial interest rate for new pairs (NAD-scaled)
    pub initial_rate: u64,
}

Fields

exp_rate
u64
Exponential rate parameter in NAD/millisecond. Derived from half_life_ms as ln(2) / half_life_ms. Controls how quickly rates adjust.
target_util_start
u64
Lower bound of target utilization band (NAD-scaled). Below this, rates decay exponentially.
target_util_end
u64
Upper bound of target utilization band (NAD-scaled). Above this, rates grow exponentially.
half_life_ms
u64
Rate adjustment half-life in milliseconds. Lower = faster adjustments, Higher = slower adjustments. Bounded by MIN_RATE_HALF_LIFE_MS and MAX_RATE_HALF_LIFE_MS.
min_rate
u64
Minimum interest rate floor (NAD-scaled). Rate will not drop below this value.
max_rate
u64
Maximum interest rate ceiling (NAD-scaled). Rate will not exceed this value. Set to 0 for no cap.
initial_rate
u64
Starting interest rate for new pairs using this model (NAD-scaled).

Rate Calculation

The rate model uses an exponential formula with three utilization bands:

Utilization Bands

BandConditionRate Behavior
LowU<U < target_util_startRate decays exponentially toward min_rate
Optimaltarget_util_start U\leq U \leq target_util_endRate stays flat
HighU>U > target_util_endRate grows exponentially, capped at max_rate

Rate Evolution

r(t)=r(t1)e±kΔtr(t) = r(t-1) \cdot e^{\pm k \cdot \Delta t} Where k=ln(2)/half_life_msk = \ln(2) / \text{half\_life\_ms}

Interest Accrual

Interest is calculated using the integral of the rate function over time: Interest=Debt×Integral\text{Interest} = \text{Debt} \times \text{Integral} Integral=rendrstartk÷MILLISECONDS_PER_YEAR\text{Integral} = \frac{r_{\text{end}} - r_{\text{start}}}{k} \div \text{MILLISECONDS\_PER\_YEAR} When rates hit min/max caps during a time window, the integral is split into the exponential portion and a flat portion.

Validation Rules

Parameters must satisfy:
  • target_util_start < target_util_end
  • target_util_start >= MIN_TARGET_UTIL_BPS (1%)
  • target_util_end <= MAX_TARGET_UTIL_BPS (100%)
  • MIN_RATE_HALF_LIFE_MS <= half_life_ms <= MAX_RATE_HALF_LIFE_MS
  • min_rate <= max_rate (if max_rate > 0)
  • min_rate <= initial_rate <= max_rate (if max_rate > 0)

Default Values

ParameterDefaultDescription
target_util_start33% (3300 bps)Start of optimal band
target_util_end66% (6600 bps)End of optimal band
half_life_ms1 hour (3,600,000 ms)Rate adjustment speed
min_rate1% (100 bps)Rate floor
max_rate0 (no cap)Rate ceiling
initial_rate5% (500 bps)Starting rate