Skip to content

Add Kamino/Solend-style lending program example#44

Open
mikemaccana wants to merge 3 commits into
mainfrom
claude/busy-pasteur-eMVnc
Open

Add Kamino/Solend-style lending program example#44
mikemaccana wants to merge 3 commits into
mainfrom
claude/busy-pasteur-eMVnc

Conversation

@mikemaccana

Copy link
Copy Markdown
Collaborator

What

A new finance/lending/anchor example: a Kamino/Solend-style borrow/lend program built with the techniques the most-used Solana lending protocols share.

How it works

  • Reserves (one per asset) own a program-controlled liquidity vault and a share-token mint. Suppliers deposit_reserve_liquidity to mint share tokens; the share/liquidity exchange rate rises as interest accrues, so redeem_reserve_collateral returns more than was deposited. available_liquidity (not the vault's raw balance) is the source of truth, which defeats the empty-pool share-inflation attack.
  • Interest uses a kinked utilization curve (min/optimal/max borrow rate around optimal_utilization) compounded through a cumulative borrow-rate index advanced by refresh_reserve. Each borrow stores scaled debt (principal ÷ index at borrow time), so every obligation's debt grows automatically.
  • Obligations hold posted share-token collateral and borrows. refresh_obligation recomputes borrowed_value, allowed_borrow_value (Σ collateral × LTV) and unhealthy_borrow_value (Σ collateral × liquidation threshold) from oracle prices. borrow_obligation_liquidity / withdraw_obligation_collateral are gated by the LTV limit; liquidate_obligation repays an unhealthy obligation's debt (capped by the close factor) and seizes collateral plus a bonus.
  • Oracle: PriceFeed mirrors a Switchboard On-Demand pull feed (mantissa + exponent + slot); a set_price handler writes it directly for deterministic LiteSVM tests, with the production Switchboard mapping documented in the README. Freshness is checked in slots.
  • Math: integer-only u128 (no floats, no fixed-point crates), ratios scaled by FIXED_POINT_SCALE (10^18), every conversion rounding in the protocol's favour.

A worked directional-short example (supply USDC, borrow + sell NVDAx, pay a variable rate, buy back, repay) is in the README.

Tests

Rust + LiteSVM, run with cargo test (Anchor's anchor test). 18 tests across 6 files cover supply/redeem, borrow/repay, withdraw, interest accrual, liquidation with bonus and close-factor cap, the inflation guard, stale reserve/price rejection, and rounding/health-boundary edges. anchor build (or cargo build-sbf) must run first so the tests can load the compiled .so.

https://claude.ai/code/session_01RwE8f8ahP5S6SDNTsXmpj9


Generated by Claude Code

claude added 3 commits June 2, 2026 21:33
A finance/lending Anchor example implementing the core techniques of the
most-used Solana lending protocols:

- Per-asset reserves with a program-owned liquidity vault and a share-token
  mint; the share/liquidity exchange rate rises as interest accrues.
- Utilization-based kinked interest-rate curve compounded through a cumulative
  borrow-rate index, with per-obligation scaled debt.
- Per-borrower obligations: post share-token collateral, borrow against it up
  to a loan-to-value limit, repay, withdraw.
- Oracle-priced health and close-factor-capped liquidation with a seize bonus.
- Switchboard-On-Demand-shaped price feed with a set_price test writer.
- Integer-only u128 math (no floats/fixed-point), rounding always in the
  protocol's favour; available_liquidity as source of truth defeats the
  empty-pool share-inflation attack.

Rust + LiteSVM tests cover supply/redeem, borrow/repay, withdraw, interest
accrual, liquidation, the inflation guard, stale reserve/price rejection, and
rounding edges (18 tests).

https://claude.ai/code/session_01RwE8f8ahP5S6SDNTsXmpj9
`anchor build`'s IDL generation compiles a generated test under the
idl-build feature, where the `#[constant]` macro mis-evaluates the 1e18
u128 literal as i32 ("literal out of range for i32"), failing CI. These
values don't need to be in the IDL, so they're plain `pub const`s now.

https://claude.ai/code/session_01RwE8f8ahP5S6SDNTsXmpj9
A Quasar (zero-copy, no_std) port of finance/lending, mirroring the shipped
Quasar escrow/vault examples' fixed-size-account idiom:

- Isolated single-collateral / single-borrow obligations (fixed-size accounts)
  rather than the Anchor version's Vec-based multi-asset obligation. Quasar does
  support Vec<T, N> and CtxWithRemaining, but the DeFi examples favour fixed-size
  positions, so this follows that idiom.
- Interest accrues inline per instruction instead of via a separate refresh.
- Keeps every core technique: share-token deposits, a kinked-curve cumulative
  interest index, oracle-priced health, and close-factor liquidation with a bonus.
- Integer-only u128 math scaled by 1e18, rounding in the protocol's favour.

quasar-svm tests cover supply/redeem, borrow up to the LTV limit (and rejection
beyond), repay, interest accrual lifting share value, and liquidation of an
unhealthy position with the healthy path rejected.

https://claude.ai/code/session_01RwE8f8ahP5S6SDNTsXmpj9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants