> ## Documentation Index
> Fetch the complete documentation index at: https://kamino.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Interest Rate Curve

> Calculate how borrow and supply APY change based on pool utilization

<Note>
  The interest rate curve shows how borrow and supply APY change as pool utilization increases from 0% to 100%, where utilization represents the share of supplied liquidity that is borrowed.
</Note>

## Calculate Interest Rate Curve

Generate curve points showing APY at different utilization levels.

<Steps>
  <Step>
    ### Import Dependencies

    Import the required packages for Solana RPC communication and Kamino SDK operations.

    ```typescript theme={null}
    import { createSolanaRpc, address } from '@solana/kit';
    import { KaminoMarket, DEFAULT_RECENT_SLOT_DURATION_MS, SLOTS_PER_SECOND, PROGRAM_ID } from '@kamino-finance/klend-sdk';
    import { getBorrowRate, calculateAPYFromAPR } from '@kamino-finance/klend-sdk/dist/classes/utils';
    ```
  </Step>

  <Step>
    ### Configure Market and Reserve

    Set up the lending market, reserve address, and calculation parameters.

    ```typescript theme={null}
    const LENDING_MARKET_ID = address('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
    const RESERVE_ADDRESS = address('ESCkPWKHmgNE7Msf77n9yzqJd5kQVWWGy3o5Mgxhvavp');
    const STEP = 0.05;
    ```

    <Note>
      The STEP value determines curve granularity: 0.05 = 21 points, 0.01 = 101 points. Smaller steps provide smoother curves but increase computation.
    </Note>
  </Step>

  <Step>
    ### Load Market and Reserve

    Initialize RPC connection and load the market and reserve data.

    ```typescript theme={null}
    const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
    const market = await KaminoMarket.load(rpc, LENDING_MARKET_ID, DEFAULT_RECENT_SLOT_DURATION_MS, PROGRAM_ID);
    const reserve = market!.getReserveByAddress(RESERVE_ADDRESS);

    if (!reserve) throw new Error(`Reserve ${RESERVE_ADDRESS} not found`);

    const currentSlot = await rpc.getSlot().send();
    ```

    <Info>
      The `getReserveByAddress` method retrieves reserve configuration including the borrow rate curve points and protocol parameters needed for APY calculations.
    </Info>
  </Step>

  <Step>
    ### Extract Borrow Curve Points

    Convert the reserve's borrow rate curve from basis points to decimal values.

    ```typescript theme={null}
    const ONE_HUNDRED_PCT_IN_BPS = 10_000;
    const borrowCurve: [number, number][] = [];

    for (const { utilizationRateBps, borrowRateBps } of reserve.state.config.borrowRateCurve.points) {
      borrowCurve.push([utilizationRateBps / ONE_HUNDRED_PCT_IN_BPS, borrowRateBps / ONE_HUNDRED_PCT_IN_BPS]);
      if (utilizationRateBps === ONE_HUNDRED_PCT_IN_BPS) break;
    }
    ```

    <Info>
      The borrow curve defines interest rates at specific utilization thresholds and interpolates between them. Rates rise sharply after 80% utilization to discourage the pool from becoming fully utilized.
    </Info>
  </Step>

  <Step>
    ### Calculate Adjustment Parameters

    Get parameters needed to convert per-slot rates to annual APY.

    ```typescript theme={null}
    const slotDuration = DEFAULT_RECENT_SLOT_DURATION_MS;
    const slotAdjustmentFactor = 1000 / SLOTS_PER_SECOND / slotDuration;
    const protocolTakeRatePct = 1 - (reserve.state.config.protocolTakeRatePct / 100);
    const fixedHostInterestRate = reserve.getFixedHostInterestRate();
    ```

    <Info>
      **Key Parameters Explained**

      * **Slot Adjustment Factor**: Converts per-slot rates to annual rates. Solana has \~2 slots per second with average 400ms duration.
      * **Protocol Take Rate**: The percentage of borrow interest paid to suppliers. If protocol takes 10%, suppliers receive 90% of interest paid by borrowers.
      * **Fixed Host Interest Rate**: A small base rate added to all borrows, ensuring borrowers pay at least a minimum rate even at 0% utilization.
    </Info>
  </Step>

  <Step>
    ### Generate Curve Points

    Calculate borrow and supply APY at each utilization level.

    ```typescript theme={null}
    const curvePoints = [];
    const numSteps = Math.round(1.0 / STEP);

    for (let i = 0; i <= numSteps; i++) {
      const utilization = i / numSteps;
      const borrowAPR = getBorrowRate(utilization, borrowCurve) * slotAdjustmentFactor;
      const borrowRate = calculateAPYFromAPR(
        fixedHostInterestRate.mul(slotAdjustmentFactor).add(borrowAPR).toNumber()
      );
      const supplyRate = calculateAPYFromAPR(utilization * borrowAPR * protocolTakeRatePct);

      curvePoints.push({
        utilization: utilization,
        borrowApy: borrowRate * 100,
        supplyApy: supplyRate * 100
      });
    }
    ```

    <Info>
      **How the Calculation Works**

      1. `getBorrowRate` interpolates the borrow rate from the curve at the given utilization
      2. `calculateAPYFromAPR` converts APR to APY: `APY = (1 + rate/periods)^periods - 1`, accounting for compound interest per slot
      3. Supply APY formula: `supplyAPY = utilization × borrowAPR × (1 - protocolFee)` - suppliers earn interest only on borrowed funds, minus the protocol fee
    </Info>
  </Step>

  <Step>
    ### Build Result with Current Metrics

    Combine the curve data with current reserve metrics.

    ```typescript theme={null}
    const result = {
      symbol: reserve.symbol,
      reserveAddress: RESERVE_ADDRESS.toString(),
      currentUtilization: reserve.calculateUtilizationRatio(),
      currentBorrowApy: reserve.totalBorrowAPY(currentSlot) * 100,
      currentSupplyApy: reserve.totalSupplyAPY(currentSlot) * 100,
      curvePoints
    };

    console.log(JSON.stringify(result, null, 2));
    ```

    <Check>
      The result includes the reserve symbol, current utilization and APY values, plus an array of curve points. Each curve point contains the utilization level, borrow APY, and supply APY at that utilization. This data can be used to visualize the interest rate curve with charting libraries.
    </Check>
  </Step>
</Steps>

## Understanding the Results

The curve shows how rates change with utilization:

* **Low utilization (0-50%)**: Borrow rates are low to encourage borrowing, supply rates are minimal
* **Medium utilization (50-80%)**: Rates increase moderately to balance supply and demand - this is the target range
* **High utilization (80-100%)**: Rates increase sharply to incentivize repayment and new deposits

### Example Output

```json theme={null}
{
  "symbol": "USDG",
  "reserveAddress": "ESCkPWKHmgNE7Msf77n9yzqJd5kQVWWGy3o5Mgxhvavp",
  "currentUtilization": 0.7888,
  "currentBorrowApy": 8.2,
  "currentSupplyApy": 5.8,
  "curvePoints": [
    { "utilization": 0.0, "borrowApy": 2.1, "supplyApy": 0.0 },
    { "utilization": 0.25, "borrowApy": 3.5, "supplyApy": 0.8 },
    { "utilization": 0.5, "borrowApy": 5.2, "supplyApy": 2.3 },
    { "utilization": 0.75, "borrowApy": 8.9, "supplyApy": 5.9 },
    { "utilization": 1.0, "borrowApy": 45.2, "supplyApy": 40.1 }
  ]
}
```
