Worked example · 2025-03
zkLend precision-loss collateral-accounting exploit — Starknet — 2025-02-12
Summary
zkLend is a Starknet-native money-market protocol implementing the Compound v2 lending-pool design pattern in Cairo. Users deposit collateral assets into lending pools, receive share tokens representing pool-share, and may borrow against the share-token balance. The share-price computation derives from the ratio of total reserves to total share supply — a formula that becomes degenerate in markets with zero or near-zero share supply, where small donations to the pool reserves can distort the share-price output in the attacker's favour during share-mint operations.
On 2025-02-12 an attacker exploited the precision-loss / rounding-error in zkLend's share-price computation to drain approximately $9.6M-equivalent across the USDC, ETH, and STRK markets on Starknet. The attack sequence followed the canonical pattern established across the Compound v2 fork cohort: (1) open a flash loan on Starknet for working capital, (2) deposit a dust amount into a target market with low share supply, (3) donate tokens directly to the market contract to inflate reserves without minting new shares, (4) mint share-priced positions at the distorted share price, (5) redeem at the inflated price, (6) repay the flash loan, (7) extract the difference after flash-loan repayment. The cycle was repeated across multiple markets to scale extraction.
The proximate cause was the design-pattern-level vulnerability inherited from the Compound v2 lending-pool pattern, with the Cairo-language port preserving the underlying share-price computation without retrofitting the canonical first-depositor / market-bootstrap requirement. zkLend had been audited prior to the incident; the audit reports did not flag the precision-loss class explicitly — consistent with the recurring 2023–2025 OAK pattern that audits scoped at the implementation level routinely miss vulnerabilities existing at the design-pattern level.
For OAK's purposes the case is a clean T9.001 + T9.002 chain. The novel contribution of this worked example is documenting the precision-loss class crossing chain boundaries to Starknet / Cairo, confirming that the vulnerability class is tied to the design pattern, not to any specific VM or source language.
Timeline (UTC)
| When | Event | OAK ref |
|---|---|---|
| Pre-2023-04 | Compound v2 lending-pool design pattern in production across EVM protocols; precision-loss vulnerability latent in share-price computation under low-share-supply conditions | T9.001 surface (latent, design-pattern-level) |
| 2023-04-15 | Hundred Finance exploited via same precision-loss class on Optimism (~$7.4M); root cause disclosed publicly within days | T9.001 cohort case 1 |
| 2023-06-16 | Midas Capital exploited via same class on BNB Chain (~$600K); vulnerability re-confirmed | T9.001 cohort case 2 |
| 2023-11-01 | Onyx Protocol exploited via same class on Ethereum (~$2.1M) | T9.001 cohort case 3 |
| 2024-05-15 | Sonne Finance exploited via same class on Optimism (~$20M) | T9.001 cohort case 4 |
| 2024-09-26 | Onyx Protocol exploited again via same class on Ethereum (~$3.8M) — within-protocol repeat failure | T9.001 cohort case 5 |
| Pre-event (zkLend) | zkLend deploys Cairo-language Compound v2 fork on Starknet without first-depositor market-bootstrap requirement | T9.001 surface (latent, cross-chain) |
| Pre-event (attacker) | Attacker funds wallet via Tornado Cash on Ethereum; bridges seed capital to Starknet via StarkGate; analyses zkLend's share-price computation | (off-OAK pre-event) |
| 2025-02-12 (attack tx window) | Attacker opens flash loan on Starknet; executes donation-then-mint cycle across zkLend's USDC, ETH, and STRK markets; extracts ~$9.6M | T9.001 + T9.002 extraction |
| 2025-02-12 (within hour) | zkLend operations team detects drain; pauses affected markets | (operator response) |
| 2025-02-13 | zkLend publicly offers 10% white-hat bounty; attacker initially engages in negotiation via on-chain message-data | (negotiation phase) |
| 2025-02 — 2025-03 | Negotiation yields partial recovery ( |
(partial recovery, ~20%) |
| 2025-03 onward | Remaining proceeds bridged from Starknet back to Ethereum via StarkGate; laundered through Tornado Cash | T7.001 (Mixer-Routed Hop) |
| 2025-03 onward | zkLend winds down operational support for affected markets | (recovery state — partial, protocol wind-down) |
What defenders observed
- The precision-loss / rounding-error class travels with the design pattern, not with the VM. zkLend's Cairo-language port reproduced the same vulnerability that had fired five times across the EVM Compound v2 fork cohort (Ethereum, Optimism, BNB Chain). The defender lesson is that design-pattern-level vulnerabilities transcend source-language and chain boundaries — any protocol implementing the lending-pool design pattern on any chain must implement the first-depositor / market-bootstrap requirement as a hard architectural invariant.
- The Compound v2 fork cohort is now six worked examples deep across four chains. The cohort spans Hundred Finance (Optimism), Midas Capital (BNB Chain), Onyx Protocol (Ethereum, twice), Sonne Finance (Optimism), and zkLend (Starknet). The failure class continues to fire approximately every 6–9 months, and has now crossed from EVM to non-EVM chains. Contributor-facing documentation should treat the cohort as a canonical case for design-pattern-level vulnerability cataloguing in the Mitigations layer.
- Audits scoped at the implementation level routinely miss design-pattern-level vulnerabilities. zkLend had been audited; the precision-loss class was not flagged. Defender practice should include design-pattern-level threat-modeling as a distinct audit dimension — with explicit checklist items for known design-pattern-level vulnerability classes including the precision-loss / rounding-error class — separate from implementation-level line-and-function audit work.
- Negotiation with attacker produced partial recovery (~20%) but the bounty was ultimately declined. The zkLend case documents the negotiation-as-partial-recovery-primitive pattern: a public 10% white-hat bounty, on-chain message-data engagement, and ~20% realised recovery. The defender practice insight is that negotiation-with-attacker is a real recovery primitive that produces partial recovery in expectation (10–30% band across the 2024–2025 cohort), not full recovery, and should be treated accordingly in incident-response planning.
What this example tells contributors writing future Technique pages
- T9.001 (Precision-Loss / Rounding-Error Manipulation) is the correct primary classification for the empty-market subclass, distinct from the spot-price manipulation variants (thin-input oracle, PMM-curve, AMM constant-product). The zkLend case is the canonical 2025 Starknet / Cairo worked example — the Compound v2 fork cohort already provides a deep evidence base for the subclass.
- T9.002 (Flash-Loan-Funded Attack) is the working-capital precondition that scaled per-iteration rounding-favourable extraction to the ~$9.6M realised figure. The T9.001 + T9.002 combination is the canonical pattern for this class and should be documented as such on both technique pages.
- The cross-chain reach of the Compound v2 fork cohort is a structural argument for design-pattern-level vulnerability cataloguing in the Mitigations layer. The cohort now spans Ethereum, Optimism, BNB Chain, and Starknet. Cohort-monitoring for fork-protocols should extend across chain boundaries and be scoped at the design-pattern level, not at the chain or source-language level.
- Negotiation-as-partial-recovery-primitive deserves explicit Mitigations-layer coverage. zkLend (February 2025) is one of the cleaner 2025 worked examples, alongside the broader 2024–2025 cohort. The realised-recovery-rate distribution (10–30% for cases where the negotiation surface is engaged) should inform defender incident-response planning.
Public references
[zklendpostmortem2025]— zkLend operator-side public statement on the February 2025 incident, including the 10% white-hat bounty offer, the negotiation timeline, and the partial-recovery outcome.[cairosecurityclanzklend2025]— Cairo Security Clan post-incident technical analysis of the zkLend precision-loss exploit, including the Cairo-specific share-price computation analysis.[nethermindzklend2025]— Nethermind Security forensic analysis of the zkLend attack transaction trace.[slowmistzklend2025]— SlowMist incident analysis covering Tornado Cash funding-source tracking, StarkGate bridging, and the post-event laundering chain.[peckshieldzklend2025]— PeckShield headline figures and on-chain analytics for the zkLend February 2025 drain.[halbornhundred2023]— Halborn post-incident analysis of the April 2023 Hundred Finance exploit — the first cohort case establishing the precision-loss class.[blocksecmidas2023]— BlockSec forensic analysis of the June 2023 Midas Capital exploit — second cohort case.[blocksecsonne2024]— BlockSec / post-incident analytics of the May 2024 Sonne Finance exploit — 2024 cohort case.[halbornonyx2024]— Halborn / BlockSec forensic analysis of the 2023–2024 Onyx Protocol exploits — within-protocol repeat-failure cases.