Paboxo

Interest rates

A two-slope curve, and why it bends where it does.

The borrow rate is a function of utilisation — how much of the Earn vault's USDG is currently borrowed. It is measured once, for the whole vault, and every market that lends from the vault prices at that one figure:

utilisation = B / A
B = Σ totalBorrowAssets            over the vault's markets
A = vault's idle USDG + Σ totalSupplyAssets

B is everything borrowed from the vault's markets. A is everything the vault has to lend: its idle USDG plus what it already has in markets. Reserves are not counted; they belong to the protocol. The vault stores the result and exposes it as utilization(); the interest rate model's utilizationOf(router) returns the figure a market's rate uses.

Each market keeps its own curve, so one utilisation does not mean one rate: at the same utilisation, each market charges its own. A borrow in one market raises the rate in all of them, because it takes from the same pool of lenders' USDG.

The vault does not push deposits into markets (its supply queue is empty): new USDG stays idle, and a market pulls from it when a borrow needs more cash than the market holds. Moving USDG from idle into a market does not change A, so it does not change the rate. Every market prices at the same vault-wide utilisation, including a market with no debt of its own. The arithmetic, with figures read from the chain, is on interest rate model.

The curve

Two slopes meeting at a kink. Every market has its own curve; they share the kink, the max rate and the max utilisation:

MarketBase rate, at 0%Rate at the kinkKinkMax rate, at 100%Max utilisation
SPY / USDG0.5%6%80%100%100%
WETH / USDG0.5%7%80%100%100%
QQQ / USDG0.5%7%80%100%100%
NVDA / USDG1%9%80%100%100%
MSFT / USDG1%9%80%100%100%
AAPL / USDG1%9%80%100%100%
GOOGL / USDG1%9%80%100%100%
TSLA / USDG1%12%80%100%100%
SPCX / USDG1.5%14%80%100%100%
AMD / USDG1.5%14%80%100%100%

Set by the protocol Safe (transaction nonce 4, executed at block 96020636 on 23 October 2026) and read from the interest rate model at block 96027397. Until then all five markets shared 0.5% / 8% / 100% with a kink at 80% and a max utilisation of 90%. MSFT/USDG and AAPL/USDG were listed on 27 October 2026 with NVDA/USDG's curve (read at block 99388687). QQQ/USDG, GOOGL/USDG and AMD/USDG were listed on 13 November 2026 with WETH/USDG's, NVDA/USDG's and SPCX/USDG's curves respectively (read at block 113204091).

Riskier collateral pays more. The markets' only lender is the shared Earn vault, so its depositors are the ones who absorb bad debt first if a liquidation comes too late. A market whose collateral can fall further between two prices pays them more for that risk. SPY is an index and the least volatile; QQQ is an index too, of a narrower set of stocks, and pays WETH's rate; WETH trades around the clock, so there is no weekend gap; NVDA, MSFT, AAPL and GOOGL are single stocks; TSLA, SPCX and AMD are the most volatile, and pay the most.

Below the kink a market's rate climbs linearly from its base rate to its kink rate. Above it the second slope runs from the kink rate to the max rate at 100% utilisation:

below the kink:  rate = base + utilisation / 80% × (kink rate − base)
above the kink:  rate = kink rate + (utilisation − 80%) / 20% × (100% − kink rate)
UtilisationSPYWETH, QQQNVDA, MSFT, AAPL, GOOGLTSLASPCX, AMD
0%0.5%0.5%1%1%1.5%
40%3.25%3.75%5%6.5%7.75%
80%6%7%9%12%14%
90%53%53.5%54.5%56%57%
100%100%100%100%100%100%

Utilisation above 100% is clamped, so the rate never exceeds the max rate.

Max utilisation is a separate limit, and it is 100%. A borrow reverts MaxUtilizationReached when the vault's utilisation after it would be at or above the borrowing market's max utilisation, whichever market it is made in. At 100% that means borrowing is allowed until the vault is fully lent: only a borrow that would take utilisation to exactly 100% reverts. The headroom is shared: what one market borrows, the others can no longer borrow. maxBorrowable() on a market's router returns the largest borrow it would accept now. Utilisation can also move without a new borrow — interest accrues onto the debt, and lenders can withdraw idle USDG — and the rate keeps following the curve.

There is therefore no guaranteed cash buffer for lenders who want to withdraw. What is left to keep one is price: past the kink, every market's rate climbs steeply towards 100%.

Why the bend

A lending market has one lever to keep withdrawals possible, and it is price. Below the kink there is plenty of idle liquidity and no reason to discourage borrowing. Above it, every additional borrow eats into the idle USDG that lets lenders exit — and with max utilisation at 100%, nothing else reserves it — so the rate rises fast enough that borrowers repay and suppliers arrive.

The steepness is not a fee. It is the mechanism that makes the pool self-correcting without anyone intervening.

What lenders receive

supply rate = borrow rate × (totalBorrowAssets / totalSupplyAssets) × (1 − reserve factor)

That is the return on what the Earn vault has in the market. The ratio is the market's own borrowed over supply held, not the vault-wide utilisation the curve uses. An Earn depositor receives the vault's blended return across markets, less the vault's fee — see Earn vault. Before the fee, that blend is each market's borrow rate weighted by its share of the debt: Σ (market's borrow rate × its totalBorrowAssets) / A × (1 − reserve factor). If all of the debt were in one market, it would be borrow rate × utilisation × (1 − reserve factor).

Two things follow. A high borrow rate at low utilisation earns lenders little, because few borrowers are paying it. And the reserve factor is a real deduction — 10% on every market, even though the stored value reads 0. Read the effective value from reserveFactor(router): reading the stored 0 as zero overstates the supply APY.

Accrual

Interest is owed every second, but it is written to storage only when accrueInterest() runs. Each run charges the whole window since the last one, linearly, at the rate of that window, and adds it to the debt — so the next run charges interest on that interest. Interest therefore compounds at every booking, not continuously and not on a schedule, and a busy market compounds more often than a quiet one.

accrueInterest() runs automatically on borrow, repay, liquidation, supplying and withdrawing collateral, and every Earn vault deposit or withdrawal. Because every market's rate depends on the vault's utilisation, the vault only stores a new utilisation after every market has accrued at the old one: each borrow, repay and liquidation calls the vault's accrueInterestAll(), and every vault deposit and withdrawal does the same. Between those moments every market's rate is fixed, so no market is charged at a rate set by later activity. Both calls are permissionless: anyone can make them. There is no action a borrower or lender needs to take. Formulas, rounding and a worked example are on interest accrual; what compounding does to the annual figure is on APR and APY.

Curves are per market

The curve is configured per market on the interest rate model, keyed by the market's router address, and each market's is different — see the curve. One is changed without touching the others: setLendingPoolRateCurve(router, …) sets one market's base rate, kink rate, kink, max utilisation and max rate in a single call. The utilisation it is applied to is always the vault's.

On this page