Skip to main content
Borrower interest increases market debt and is divided between suppliers and protocol revenue. The pool applies those changes through supply and borrow indexes, so individual account balances do not need a separate interest write.

Scaled balances

Positions and market totals store scaled RAY balances. RAY is 10^27; both indexes start at RAY, representing 1.0. The scale conversion is:
Supply uses supply_index; debt uses borrow_index. At index RAY, one whole 7-decimal token corresponds to 10^27 scaled RAY units and 10^7 native units. The equations above show units before rounding. Amount views round half-up; full withdrawals pay the floor-valued supply balance, and full repayments need the ceiling-valued debt. Use get_collateral_amount and get_borrow_amount for display and simulate settlement. Risk valuation has its own conservative rounding rules. These conversions apply to raw contract shares. The v1 API already applies interest indexes: its amountRaw is in token base units, with supply rounded down and debt rounded up. Do not apply RAY conversion to it again.

Utilization

Utilization measures borrowed value as a fraction of supplied value:
It is zero when supplied value is zero and is capped at RAY when selecting the borrow rate. The separate max_utilization setting limits new borrowing and ordinary withdrawal; liquidation withdrawals skip that limit. See Market parameters.

Borrow-rate model

The annual borrow rate has three linear regions separated by mid_utilization and optimal_utilization. All rate and utilization inputs use RAY. Using normalized ratios for readability, the curve is:
The implementation rounds intermediate multiplications and divisions half-up. Parameters satisfy base <= slope1 <= slope2 <= slope3 <= max and 0 < mid < optimal < RAY. max_utilization is an admission limit and does not add a breakpoint to this curve.

Accrual

Pool accounting operations and update_indexes advance interest to ledger time. The annual borrow rate becomes a RAY-scaled rate per millisecond. Elapsed time is processed in chunks of at most one year, using a Taylor approximation of the exponential through the eighth-order term:
Truncation alone underestimates the exponential: the relative shortfall for a one-year chunk is about 2.4e-4 at 200% APR and 1.2e-12 at 20% APR. Fixed-point rounding and rate conversion can produce a small overestimate when truncation is smaller. Accrual cadence also affects intermediate utilization, rates, and rounding.
The borrow and supply indexes are capped at 1e36. The borrow index therefore has a 1e9 growth factor from its initial value. At its ceiling, debt interest stops growing and no further borrower interest reaches suppliers. The clamp has no dedicated error or ceiling event; monitoring must read index values.
Interest accrual never lowers the supply index. Bad-debt socialization can lower it, as described below.

Splitting interest

Accrued interest is the difference between debt values at the two indexes. The separate half-up roundings matter:
Supplier rewards increase supply_index. Any reward amount that the index change cannot represent is included in the amount considered for protocol revenue. Conversion into revenue shares floors and is capped by available integer headroom, so exact allocation of every raw unit is not guaranteed. The displayed supply APR uses utilization, borrow APR, and the supplier share:
At 80% utilization, 5% borrow APR, and a 10% reserve factor, supply APR is 0.8 * 0.05 * 0.9 = 3.6%. These are annual rates, not a promise of a fixed yield; realized earnings depend on utilization and accrual over time. Contract rate views return annual RAY-scaled APR. The v1 API instead returns display APYs as fractions: 0.05 means 5%. Keep the rate type and scale with the value. Converting RAY to a decimal fraction does not itself convert APR to APY.

Protocol revenue

Revenue is a scaled supply claim included in total supply: 0 <= revenue <= supplied. It follows the supply index until claimed and shares any market write-down. claim_revenue syncs indexes, converts the claim to underlying tokens, caps the payout at available cash, and burns the corresponding revenue shares. The pool sends the payout to the controller, which forwards it to the configured accumulator. See Controller ABI.

Bad debt and recapitalization

Bad-debt socialization lowers the affected market’s supply index. All remaining supply claims in that market absorb the reduction, including unclaimed revenue. Other markets have separate accounting. The index cannot fall below SUPPLY_INDEX_FLOOR_RAW = RAY / 1_000. At that floor, the same deposit creates 1,000 times as many shares as at index 1.0, reducing available deposit headroom. The floor can also leave a market shortfall. See Bad-debt accounting for the write-down formula and Liquidations for cleanup eligibility. Anyone may call recapitalize(payer, hub_asset, amount), including during global pause. It credits measured receipts only up to the market’s actual shortfall, refunds excess, and returns the amount applied. It repairs backing without restoring a written-down supply index. It only covers the market shortfall.