# Interest Rates & Quotas

> Markdown export of the Gearbox Protocol documentation page for agents and retrieval systems.

Canonical page: https://docs.gearbox.finance/developers/gm-markets-rates
Source file: content/developers/gm-markets-rates.mdx
Section router: https://docs.gearbox.finance/developers/llms.txt
Section full export: https://docs.gearbox.finance/developers/llms-full.txt

Gearbox uses a two-part interest model: a **base interest rate** driven by pool utilization, and **quota rates** that add per-token fees for collateral exposure. Together they determine the total borrowing cost for credit accounts.

## Base Interest Rate Model

The base rate follows a linear kinked model with three slopes, similar to Aave/Compound. Parameters are set per pool.

| Parameter | Description |
|---|---|
| `U1` | First utilization kink (basis points) |
| `U2` | Second utilization kink (basis points) |
| `Rbase` | Base rate at 0% utilization |
| `Rslope1` | Rate slope between 0 and U1 |
| `Rslope2` | Rate slope between U1 and U2 |
| `Rslope3` | Rate slope above U2 (steep penalty zone) |

### Reading Model Parameters

```typescript
import { iLinearInterestRateModelV3Abi } from "@gearbox-protocol/sdk";

// Get the IRM address from the pool
const irmAddress = await publicClient.readContract({
  address: poolAddress,
  abi: iPoolV3Abi,
  functionName: "interestRateModel",
});

// Query model parameters
const params = await publicClient.readContract({
  address: irmAddress,
  abi: iLinearInterestRateModelV3Abi,
  functionName: "getModelParameters",
});

const [U1, U2, Rbase, Rslope1, Rslope2, Rslope3] = params;
console.log(`Kink 1: ${U1} bps, Kink 2: ${U2} bps`);
console.log(`Slopes: ${Rbase} / ${Rslope1} / ${Rslope2} / ${Rslope3}`);
```

### Current Rates via SDK

```typescript
const market = sdk.marketRegister.findByPool(poolAddress);
const pool = market.pool;

const RAY = 10n ** 27n;
const supplyAPY = Number(pool.supplyRate * 10000n / RAY) / 100;
const borrowAPR = Number(pool.baseInterestRate * 10000n / RAY) / 100;

console.log(`Supply APY: ${supplyAPY.toFixed(2)}%`);
console.log(`Base Borrow APR: ${borrowAPR.toFixed(2)}%`);
```

## Quota System

Quotas regulate how much pool capital can be exposed to specific collateral tokens. Each quoted token carries its own interest rate on top of the base borrow rate.

### How Quotas Work

- A credit account's "quota" for a token is the amount of debt backed by that collateral.
- Quota interest is **additive** (linear), not compounding. The PoolQuotaKeeper tracks a `cumulativeIndex` per token.
- If `totalQuoted` reaches the `limit` for a token, any transaction that increases that quota reverts with `QuotaIsOutOfBoundsException`.

### Reading Quota Parameters

```typescript
import { getContract } from "viem";
import { poolQuotaKeeperV3Abi } from "@gearbox-protocol/sdk";

// Get the QuotaKeeper address
const quotaKeeperAddress = await publicClient.readContract({
  address: poolAddress,
  abi: iPoolV3Abi,
  functionName: "poolQuotaKeeper",
});

const quotaKeeper = getContract({
  address: quotaKeeperAddress,
  abi: poolQuotaKeeperV3Abi,
  client: publicClient,
});

// Get global quota parameters for a token
const tokenParams = await quotaKeeper.read.getTokenQuotaParams([tokenAddress]);
```

The returned object contains:

| Field | Type | Description |
|---|---|---|
| `rate` | `uint16` | Annual interest rate in basis points |
| `cumulativeIndex` | `uint192` | Accumulated interest index |
| `quotaIncreaseFee` | `uint16` | One-time fee on quota increases (basis points) |
| `totalQuoted` | `uint96` | Total quota across all credit accounts |
| `limit` | `uint96` | Maximum allowed `totalQuoted` |
| `isActive` | `bool` | Whether the token is actively quoted |

### Checking Available Quota

```typescript
const tokenParams = await quotaKeeper.read.getTokenQuotaParams([tokenAddress]);
const availableQuota = tokenParams.limit - tokenParams.totalQuoted;

console.log(`Total quoted: ${tokenParams.totalQuoted}`);
console.log(`Limit: ${tokenParams.limit}`);
console.log(`Available: ${availableQuota}`);
console.log(`Rate: ${tokenParams.rate} bps`);
```

### Per-Account Quota and Interest

Query how much quota an individual credit account is consuming:

```typescript
const [quoted, outstandingInterest] = await quotaKeeper.read.getQuotaAndOutstandingInterest([
  creditAccountAddress,
  tokenAddress,
]);

console.log(`Account quota: ${quoted}`);
console.log(`Outstanding interest: ${outstandingInterest}`);
```

## Rate Setting: Gauge vs. Tumbler

Quota rates are set by an external contract implementing `IRateKeeper`. There are two models:

### GaugeV3 (Voting Model)

Used in the core protocol. GEAR token stakers vote to move rates between a `minRate` and `maxRate` for each token.

### TumblerV3 (Curator Model)

Used in the permissionless ecosystem. Curators set exact rates directly.

| Function | Description |
|---|---|
| `setRate(address token, uint16 rate)` | Set rate in basis points |
| `updateRates()` | Apply pending rate changes |
| `epochLength` | Minimum time between rate updates |

Rates set via Tumbler only take effect after `updateRates()` is called, and the Tumbler enforces an `epochLength` to prevent frequent manipulation.

## Total Borrowing Cost

The total interest rate for a credit account is:

```
Total Rate = Base Borrow Rate + Sum(Quota Rate_i * Quota_i / Debt)
```

Where each quoted token contributes its quota rate proportional to the quota amount relative to total debt.

## Next Steps

- [Insurance Mechanism](https://docs.gearbox.finance/developers/gm-markets-insurance) -- How fees fund the insurance buffer
- [Pool Operations](https://docs.gearbox.finance/developers/gm-markets-pools) -- Deposit and withdraw liquidity
- [Markets Data](https://docs.gearbox.finance/developers/gm-markets-data) -- Query pool and credit manager state
