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.
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
Verification commands (≤ 60 seconds, no Solana toolchain required)
# 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 \
-- --nocaptureExpected 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 failedFor 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.
