CoolFace
Datasetpublic

tonydav41/kamino-klend-withdrawal-cap-bypass-immunefi-2026-05-12

Kamino klend Withdrawal-Cap Cross-Interval Bypass — Immunefi PoC Bundle Filed: 2026-05-12 Target program: Kamino (Immunefi) Program ID: KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD Audited commit: a26220ce127fe571d9190011737c53e0fc09c415 (klend master HEAD / Release 1.21.0) Severity: High — Theft of unclaimed yield (Kamino program impacts-in-scope category) CVSS 3.1: 7.4 High (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L) TL;DR klend's per-reserve debt_withdrawal_cap and… See the full description on the dataset page: https://huggingface.co/datasets/tonydav41/kamino-klend-withdrawal-cap-bypass-immunefi-2026-05-12.

sourceHugging Facemitupdated 5mo agoView on Hugging Face
0likes7downloads
Dataset Card

Kamino klend Withdrawal-Cap Cross-Interval Bypass — Immunefi PoC Bundle

Filed: 2026-05-12 Target program: Kamino (Immunefi) Program ID: KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD Audited commit: a26220ce127fe571d9190011737c53e0fc09c415 (klend master HEAD / Release 1.21.0) Severity: High — Theft of unclaimed yield (Kamino program impacts-in-scope category) CVSS 3.1: 7.4 High (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L)

TL;DR

klend's per-reserve debt_withdrawal_cap and deposit_withdrawal_cap per-interval rate-limits are silently bypassed when a Remove-class operation (repay / deposit / fixed-term-borrow rollover) straddles an interval boundary. The interval-elapsed reset zeroes current_total and then immediately subtracts the requested amount, leaving the i64 counter negative at the start of the new interval. remaining_withdrawal_caps_amount() then reports config_capacity − (negative) = config_capacity + |negative|, so the next Add (borrow or collateral redeem) is permitted to exceed the configured per-interval ceiling.

The bypass is firing in production right now: on-chain getProgramAccounts of all 462 Kamino reserves on Solana mainnet shows 152 of 326 configured caps (46.6%) currently in the `current_total < 0` state. See onchain-forensics.txt.

Files

FilePurpose
findings-writeup.mdFull Immunefi-format writeup with root cause, affected lines, distinguisher, mitigation, surface enumeration
withdrawal_cap_operations__with_immunefi_test.rsKamino's actual programs/klend/src/lending_market/withdrawal_cap_operations.rs from master HEAD, with the bug-demonstrating #[cfg(test)] block appended at the bottom. The bug is the existing top of file; the test is the appended bottom
patch.diffGit diff capturing just the appended test (176 insertions, 0 deletions, 1 file)
test-transcript.txtcargo test --nocapture stdout/stderr showing both bypass cases passing (proves the bug exists by exercising Kamino's actual source)
intree-test/Self-contained Rust shim crate that compiles Kamino's exact source file via #[path] and runs the test (workaround for a pre-existing kfarms aarch64-darwin const-eval issue blocking the full klend host build — affects only the build environment, not the bug)
anchor-recipe.mdSix-step solana-test-validator on-localnet reproducer recipe for end-to-end verification
onchain-forensics.txtLive mainnet evidence: 326 reserves have caps configured, 152 are currently in the bug-triggered state, with the worst inflation at +70.6%
klend-master-commit.txtExact commit hash audited
poc-README.mdRun instructions for the in-tree test

Verification commands (≤ 60 seconds, no Solana toolchain required)

bash
# Replicate the shim crate locally
git clone https://github.com/Kamino-Finance/klend
cd klend
git checkout a26220ce127fe571d9190011737c53e0fc09c415
git apply ../patch.diff   # add the test to withdrawal_cap_operations.rs

# Then either build via the shim crate (as we did) or via klend's own test harness:
cargo test --lib --package kamino_lending \
  lending_market::withdrawal_cap_operations::utils::tests_immunefi_poc \
  -- --nocapture

Expected end-of-output:

[t=3611] remaining_withdrawal_caps_amount = 2000000 (config cap = 1000000)
[t=3611] Attempt Add 2000000 (= 2x cap) in new interval...
[t=3611] Result: ALLOWED (BUG)
=== BYPASS CONFIRMED (in-tree, Kamino's actual source) ===
test result: ok. 2 passed; 0 failed

For complete on-localnet end-to-end, see anchor-recipe.md.

On-chain forensics (live mainnet snapshot 2026-05-12)

configured_caps                                : 326
negative_caps (bug actively triggered)         : 152  (46.6%)
total_inflated_cap_units_across_protocol       : 185,040,161,743,060 raw token units

Worst observed inflation:
  74bTDxtCP2wgQiM6hFwKtKdPDTDdxYVTVkmkh4NX1Psn: cap inflated by 100% (config 2e14, current_total -1e14)
  4SnQnrZqGHT2zNW76S23um1xUYpZN8vmePSPuBP4p3fx: cap inflated by 100% (config 1e14, current_total -5e13)
  HD93Fq3gmVh3J7euJJ5MBw8Ph3ebeMFS699JQePN4XgN: cap inflated by 70.58%
  d4A2prbA2whesmvHaL88BH6Ewn5N4bTSU2Ze8P6Bc4Q: SOL Main Market SOL — cap inflated by 6225 SOL (~$1.4M extractable headroom)

Reviewers can independently verify by solana getProgramAccounts KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD and decoding each Reserve struct's config.debt_withdrawal_cap / config.deposit_withdrawal_cap.

Reporter

Filed by lendtrain (Immunefi) / tonydav41 (HuggingFace). Payout wallet: 0x97353B92b86Ed65528f1A1356448471e4823D100. KYC: Required by Kamino program — will complete at payout time per Immunefi process.