Add Kamino/Solend-style lending program example#44
Open
mikemaccana wants to merge 3 commits into
Open
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new
finance/lending/anchorexample: a Kamino/Solend-style borrow/lend program built with the techniques the most-used Solana lending protocols share.How it works
deposit_reserve_liquidityto mint share tokens; the share/liquidity exchange rate rises as interest accrues, soredeem_reserve_collateralreturns 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.min/optimal/maxborrow rate aroundoptimal_utilization) compounded through a cumulative borrow-rate index advanced byrefresh_reserve. Each borrow stores scaled debt (principal ÷ index at borrow time), so every obligation's debt grows automatically.refresh_obligationrecomputesborrowed_value,allowed_borrow_value(Σ collateral × LTV) andunhealthy_borrow_value(Σ collateral × liquidation threshold) from oracle prices.borrow_obligation_liquidity/withdraw_obligation_collateralare gated by the LTV limit;liquidate_obligationrepays an unhealthy obligation's debt (capped by the close factor) and seizes collateral plus a bonus.PriceFeedmirrors a Switchboard On-Demand pull feed (mantissa + exponent + slot); aset_pricehandler writes it directly for deterministic LiteSVM tests, with the production Switchboard mapping documented in the README. Freshness is checked in slots.u128(no floats, no fixed-point crates), ratios scaled byFIXED_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'sanchor 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(orcargo build-sbf) must run first so the tests can load the compiled.so.https://claude.ai/code/session_01RwE8f8ahP5S6SDNTsXmpj9
Generated by Claude Code