Interest Model
The InterestModel contract calculates the borrow rate and accrued interest using an exponential controller driven by the free‑debt ratio. It is a shared, pure math contract used by allLender instances.
Contract implementation
Core Calculation Function
calculateInterest
_timeElapsed seconds using an exponential controller around a target free‑debt ratio band.
Parameters:
_totalPaidDebt: Current paid (interest‑bearing) debt principalD._lastRate: Previous borrow rate mantissar_old(APR scaled by 1e18)._timeElapsed: Seconds since last accrualdt._expRate: Exponential rate constantk(derived from half‑life viawadLn(2e18)/halfLife)._lastFreeDebtRatioBps: Last observed free‑debt ratiofin basis points (0–10000), including PSM assets._targetFreeDebtRatioStartBps,_targetFreeDebtRatioEndBps: Target band[f_start, f_end]in basis points.
currBorrowRate: Updated borrow rate mantissar_new(APR scaled by 1e18).interest: Accrued interest amount over the interval.
- Let
g = exp(-k * dt). - If
f < f_start(below band): rate grows exponentiallyr_new = r_old / ginterest = D * (r_new - r_old) / (k * 365 days)
- Else if
f > f_end(above band): rate decays exponentially toward a floorr_new = max(r_old * g, r_min)withr_min = 0.5% APR- If the decay hits the floor during
dt:t_min = -ln(r_min / r_old) / kinterest = D * ((r_old - r_min) / k + r_min * (dt - t_min)) / (365 days)
- Else:
interest = D * (r_old - r_new) / (k * 365 days)
- Else (inside band): hold rate constant
r_new = r_oldinterest = D * r_old * dt / (365 days * 1e18)
Constants
MIN_RATE = 0.5% APR(as5e15in 1e18 mantissa) — lower bound for the borrow rate.
Integration Notes
- The model is stateless and pure; it is called externally by
Lenderusingtry/catchso accrual can safely skip if anything unexpected happens. - Each
Lenderstores its ownexpRate(set via half‑life) and target band; these can be adjusted before the immutability deadline. - One shared
InterestModelinstance is deployed by theFactoryand referenced by allLendercontracts.
Security Considerations
- Pure math (no state) and no external calls inside the function.
- Uses wad math (
wadExp,wadLn) and explicit floor handling to avoid overflows and negative rates.

