Skip to content

implement utilization based dynamic interest rate model for lending vault #16

@0xRektified

Description

@0xRektified

Overview

Currently LendingVault.interest_rate_bps is a hardcoded static value (30 bps). This should be replaced with a utilization-based rate curve that adjusts dynamically based on supply/demand, following the industry standard model used by Aave, Compound, and Kamino.

Background

The core metric is utilization rate:

utilization = total_borrowed / total_supplied

As more SOL is borrowed from the vault, rates increase to:

  1. Incentivize LPs to supply more liquidity
  2. Discourage excessive borrowing above optimal utilization

Implementation: Kink Rate Model

Replace interest_rate_bps: u16 with curve parameters in LendingVault:

pub base_rate_bps: u16,        // min borrow rate at 0% utilization (e.g. 200 = 2%)
pub slope1_bps: u16,           // rate added linearly up to kink (e.g. 800 = 8%)
pub slope2_bps: u16,           // rate added steeply above kink (e.g. 9000 = 90%)
pub kink_bps: u16,             // optimal utilization target (e.g. 8000 = 80%)
pub reserve_factor_bps: u16,   // protocol cut of interest (e.g. 1000 = 10%)

Add two methods to LendingVault:

  • borrow_rate_bps() -> u16 — what borrowers pay
  • supply_rate_bps() -> u16 — what LPs earn (derived from borrow rate)

Curve behaviour:

utilization:   0%              80% (kink)          100%
borrow rate:   2% ──────────── 10% ────────────── 100%
               └──── slope1 ──┘└───── slope2 ──────┘

Supply APY:

supply_rate = borrow_rate × utilization × (1 - reserve_factor)

Changes Required

  • state/lending_vault.rs — replace interest_rate_bps with curve params, add borrow_rate_bps() and supply_rate_bps() methods
  • instructions/initialize_lending_vault.rs — accept curve params as instruction args instead of hardcoded rate
  • instructions/supply.rs — use lending_vault.supply_rate_bps() for interest accrual
  • instructions/withdraw.rs — same
  • instructions/update_vault_params.rs — new authority-only instruction to update curve params post-deploy
  • tests/lending_vault.ts — add tests verifying rate changes at different utilization levels

Default Parameters

Param Value Meaning
base_rate_bps 200 2% minimum borrow rate
slope1_bps 800 +8% up to kink = 10% at 80% utilization
slope2_bps 9000 +90% above kink = up to 100% at 100% utilization
kink_bps 8000 80% optimal utilization target
reserve_factor_bps 1000 10% protocol cut from interest earned

Acceptance Criteria

  • borrow_rate_bps() returns base_rate at 0% utilization
  • borrow_rate_bps() returns base_rate + slope1 at exactly kink utilization
  • borrow_rate_bps() returns near max rate at 100% utilization
  • supply_rate_bps() is always lower than borrow_rate_bps() (due to reserve factor)
  • Authority can update curve params via update_vault_params
  • All existing lending vault tests still pass
  • New tests cover rate calculation at 0%, 50%, 80% (kink), and 100% utilization

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions