white-hat-scanner 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,401 @@
1
+ # DeFi Vulnerability Pattern Library
2
+
3
+ *Last updated: 2026-04-03. Based on analysis of 40+ post-mortems from rekt.news, DeFiLlama hacks database, and Immunefi disclosures.*
4
+
5
+ ---
6
+
7
+ ## Recent Major Hacks (2025–2026)
8
+
9
+ | Protocol | Date | Loss | Vuln Class | Audited | Bug Bounty | Bounty Ceiling vs Loss |
10
+ |---|---|---|---|---|---|---|
11
+ | Drift Trade | Apr 2026 | $285M | Compromised Admin + Fake Token Price Manip | Unknown | Unknown | — |
12
+ | Resolv | Mar 2026 | $24.5M | Private Key Compromise | Yes | Unknown | — |
13
+ | Cyrus Finance | Mar 2026 | $5M | Flash Loan Pool Shares Exploit | Unknown | No | — |
14
+ | Venus Core Pool | Mar 2026 | $3.7M | Donation Attack / Supply Cap Manipulation | Yes (4th rekt) | Yes | $1M ceiling vs $3.7M loss |
15
+ | Yieldblox (Blend V2) | Feb 2026 | $10.97M | Oracle Price Manipulation | Unknown | No | — |
16
+ | IoTeX ioTube Bridge | Feb 2026 | $4.4M | Private Key Compromise | Yes | Unknown | — |
17
+ | Moonwell | Feb 2026 | $1.78M | Oracle Misconfiguration (vibe-coded) | No (AI-generated code) | Yes | Unknown |
18
+ | Solv BRO Vault | Mar 2026 | $2.73M | Reentrancy on Callback (ERC-3525) | No | No | — |
19
+ | FoomCash | Mar 2026 | $2.26M | ZK Groth16 Trusted Setup Skipped | No | Yes ($320K "code is law") | $320K ceiling vs $2.26M loss |
20
+ | dTRINITY dLEND | Mar 2026 | $257K | Deposit Inflation / Share Price Manipulation | Unknown | Unknown | — |
21
+
22
+ **Key pattern**: Bug bounty ceiling is consistently 10–100x below actual losses. Audited protocols still get rekt on second/third incidents (Venus rekt IV, Aave rekt).
23
+
24
+ ---
25
+
26
+ ## Vulnerability Pattern Catalog
27
+
28
+ ---
29
+
30
+ ### Pattern 1: Oracle Price Manipulation
31
+
32
+ **Description**: Attacker manipulates an on-chain price oracle (often a spot AMM price or thinly-traded DEX pair) to borrow against inflated collateral or trigger artificial liquidations.
33
+
34
+ **Subtypes**:
35
+ - Spot price oracle from a single low-liquidity AMM pool
36
+ - Flash loan + swap to pump price in same transaction
37
+ - Illiquid collateral pumped 100x on a DEX (Yieldblox/Stellar DEX, Feb 2026)
38
+ - Oracle cap misconfiguration pricing asset at wrong value (Moonwell cbETH: $1.12 instead of $2,200)
39
+
40
+ **Detection — grep/static**:
41
+ ```bash
42
+ # Look for direct AMM pair getReserves() used as price
43
+ grep -r "getReserves\|slot0\|observe\|consult" contracts/ --include="*.sol"
44
+
45
+ # Look for single-block TWAP (length 0 or 1)
46
+ grep -r "twap\|TWAP\|timeWeighted" contracts/ --include="*.sol"
47
+
48
+ # Semgrep: spot price oracle
49
+ # rule: calls to UniswapV2Pair.getReserves without TWAP
50
+ ```
51
+
52
+ **Detection — Slither**:
53
+ ```bash
54
+ slither . --detect oracle-manipulation,price-manipulation
55
+ # Manual: check oracle.getPrice() call chain — does it touch AMM reserves directly?
56
+ ```
57
+
58
+ **Detection — Foundry invariant**:
59
+ ```solidity
60
+ // Invariant: borrowable amount cannot exceed X% of liquidity when price changes >10% in one block
61
+ function invariant_borrowCapAfterPriceShock() external {
62
+ uint256 prevPrice = oracle.getPrice(token);
63
+ // simulate 10x price pump
64
+ vm.prank(attacker);
65
+ flashLoanPump(token, 10e18);
66
+ uint256 newPrice = oracle.getPrice(token);
67
+ assertLt(newPrice / prevPrice, 10, "oracle accepts 10x price in single block");
68
+ }
69
+ ```
70
+
71
+ **Real examples**: Yieldblox Feb 2026 ($10.97M), Moonwell Feb 2026 ($1.78M), Mango Markets Oct 2022 ($117M), Euler Finance Mar 2023 ($197M adjacent)
72
+
73
+ **Detection difficulty**: **Medium** — easy to detect single-AMM dependency, hard to catch multi-hop manipulation chains
74
+
75
+ ---
76
+
77
+ ### Pattern 2: Flash Loan + Share Inflation (Donation / Deposit Inflation Attack)
78
+
79
+ **Description**: Attacker donates tokens directly to a vault/lending pool to inflate the price-per-share, then exploits the rounding behavior in `convertToShares()` / `balanceOf()`. Often a first-depositor attack. Related to ERC-4626 share inflation.
80
+
81
+ **Subtypes**:
82
+ - Direct token donation to vault before first deposit (dead shares bypass)
83
+ - Flash loan + donate to inflate share price, borrow against inflated shares
84
+ - Venus "supply cap bypass via donation" (Venus Rekt IV, Mar 2026)
85
+ - Cyrus Finance "Flashloan Pool Shares Exploit" (Mar 2026, $5M)
86
+ - dTRINITY "Deposit Inflation Attack" (Mar 2026, $257K)
87
+
88
+ **Detection — grep/static**:
89
+ ```bash
90
+ # Look for totalAssets() that reads raw token.balanceOf(address(this))
91
+ grep -rn "balanceOf(address(this))" contracts/ --include="*.sol"
92
+
93
+ # Look for convertToShares with division that can round to 0
94
+ grep -rn "convertToShares\|previewDeposit\|totalSupply()" contracts/ --include="*.sol"
95
+
96
+ # Missing virtual shares / dead shares defense
97
+ grep -rn "1e3\|1000\|_DEAD_SHARES\|virtual" contracts/ --include="*.sol"
98
+ ```
99
+
100
+ **Detection — Slither**:
101
+ ```bash
102
+ slither . --detect divide-before-multiply,weak-prng
103
+ # Custom detector: ERC-4626 without virtual shares protection
104
+ ```
105
+
106
+ **Detection — Foundry invariant**:
107
+ ```solidity
108
+ // Invariant: attacker cannot inflate PPS by more than 1e6 via direct donation
109
+ function invariant_sharePriceCannotBeInflated() external {
110
+ uint256 pps_before = vault.convertToAssets(1e18);
111
+ deal(address(asset), attacker, 1e30);
112
+ vm.prank(attacker);
113
+ asset.transfer(address(vault), 1e30); // direct donation
114
+ uint256 pps_after = vault.convertToAssets(1e18);
115
+ assertLt(pps_after / pps_before, 1e6, "share price inflated > 1e6x");
116
+ }
117
+ ```
118
+
119
+ **Real examples**: Venus Core Pool Mar 2026 ($3.7M), Cyrus Finance Mar 2026 ($5M), dTRINITY dLEND Mar 2026 ($257K), Sonne Finance May 2024 ($20M), Hundred Finance Apr 2023 ($7.4M)
120
+
121
+ **Detection difficulty**: **Easy** — well-understood pattern, Slither and ToB's checklist catch it; the danger is in novel variants
122
+
123
+ ---
124
+
125
+ ### Pattern 3: Reentrancy on Callback
126
+
127
+ **Description**: Contract sends ETH or calls an external contract (token hook, ERC-777 callback, ERC-3525 `_beforeValueTransfer`, NFT `onERC721Received`) before updating internal state. Attacker's callback re-enters the contract in an inconsistent state.
128
+
129
+ **Subtypes**:
130
+ - Classic single-function reentrancy (send-before-update)
131
+ - Cross-function reentrancy (update in `withdraw`, read stale in `borrow`)
132
+ - Read-only reentrancy (price read from a pool mid-callback)
133
+ - ERC-3525 value transfer callback (Solv BRO Vault Mar 2026: 22 re-entry loops, 135 BRO → 567M BRO)
134
+ - ERC-777 `tokensToSend` hook on deposit
135
+
136
+ **Detection — grep/static**:
137
+ ```bash
138
+ # Functions making external calls before state changes
139
+ grep -rn "\.call{value\|\.transfer(\|\.send(" contracts/ --include="*.sol"
140
+
141
+ # ERC-777 / ERC-3525 callback hooks
142
+ grep -rn "tokensToSend\|tokensReceived\|_beforeValueTransfer\|onERC721Received" contracts/ --include="*.sol"
143
+
144
+ # Missing ReentrancyGuard
145
+ grep -rn "nonReentrant\|ReentrancyGuard" contracts/ --include="*.sol"
146
+ # If not present: flag all external calls
147
+ ```
148
+
149
+ **Detection — Slither**:
150
+ ```bash
151
+ slither . --detect reentrancy-eth,reentrancy-no-eth,reentrancy-benign,reentrancy-events
152
+ # slither-check-erc for ERC-777/3525 hook analysis
153
+ ```
154
+
155
+ **Detection — Foundry invariant**:
156
+ ```solidity
157
+ // Invariant: token balance cannot increase by minting during deposit callback
158
+ function invariant_mintedSupplyAfterDeposit() external {
159
+ uint256 supply_before = token.totalSupply();
160
+ depositWithMaliciousCallback(attacker, 1e18);
161
+ assertLe(token.totalSupply(), supply_before + 1e18, "reentrancy inflated supply");
162
+ }
163
+ ```
164
+
165
+ **Real examples**: Solv BRO Vault Mar 2026 ($2.73M, ERC-3525), Curve Finance Jul 2023 ($73.5M, Vyper reentrancy lock bug), The DAO Jun 2016 ($60M classic)
166
+
167
+ **Detection difficulty**: **Easy for classic variants** / **Hard for cross-function and read-only** — automated tools catch basic cases, cross-function and read-only require taint analysis
168
+
169
+ ---
170
+
171
+ ### Pattern 4: Private Key Compromise / Compromised Admin
172
+
173
+ **Description**: Attacker obtains a privileged private key (deployer, multisig signer, admin) and drains funds directly or upgrades proxy to malicious implementation.
174
+
175
+ **Subtypes**:
176
+ - Single private key as sole admin (IoTeX ioTube Feb 2026: "key was the only lock")
177
+ - Leaked key from CI/CD env var, GitHub repo, or employee compromise
178
+ - Compromised multisig via social engineering or malware
179
+ - Drift Trade Apr 2026 ($285M): compromised admin + fake token price manipulation
180
+
181
+ **Detection — grep/static**:
182
+ ```bash
183
+ # Single EOA as owner without multisig/timelock
184
+ grep -rn "owner\|Ownable\|onlyOwner" contracts/ --include="*.sol"
185
+
186
+ # Missing timelocks on critical parameter changes
187
+ grep -rn "setOracle\|setFee\|upgradeTo\|_authorizeUpgrade" contracts/ --include="*.sol"
188
+ # Verify timelock in constructor args or separate contract
189
+
190
+ # Missing multisig (check for Gnosis Safe / AccessControl with role count)
191
+ grep -rn "AccessControl\|TimelockController\|Timelock" contracts/ --include="*.sol"
192
+ ```
193
+
194
+ **Detection — Slither**:
195
+ ```bash
196
+ slither . --detect controlled-delegatecall,arbitrary-send-eth,unprotected-upgrade
197
+ # slither-prop: centralization risk detector
198
+ ```
199
+
200
+ **Detection — Foundry**:
201
+ ```solidity
202
+ // Test: admin functions have timelock
203
+ function test_adminFunctionsRequireTimelock() external {
204
+ vm.prank(attacker); // non-admin
205
+ vm.expectRevert();
206
+ protocol.setOracle(address(maliciousOracle));
207
+
208
+ // Even admin: test delay exists
209
+ vm.prank(admin);
210
+ protocol.proposeOracleChange(address(newOracle));
211
+ vm.warp(block.timestamp + 1); // advance 1 second (should still revert)
212
+ vm.expectRevert("Timelock: not ready");
213
+ protocol.executeOracleChange();
214
+ }
215
+ ```
216
+
217
+ **Real examples**: Drift Trade Apr 2026 ($285M), Resolv Mar 2026 ($24.5M), IoTeX Feb 2026 ($4.4M), Ronin Bridge Mar 2022 ($625M), Harmony Horizon Jun 2022 ($100M)
218
+
219
+ **Detection difficulty**: **Easy to flag centralization risk** / **Hard to prevent off-chain key theft** — static analysis detects single-admin pattern; real fix is operational security + multisig + timelock
220
+
221
+ ---
222
+
223
+ ### Pattern 5: ZK Proof System Misconfiguration (Trusted Setup Failure)
224
+
225
+ **Description**: ZK proving system (Groth16, PLONK) requires a "trusted setup ceremony" to generate cryptographic parameters. If ceremony is incomplete or parameters reused from demo/test, attacker can forge proofs and mint arbitrary tokens.
226
+
227
+ **Subtypes**:
228
+ - Skipped MPC ceremony (used default/test `ptau` parameters)
229
+ - Copied ceremony from different circuit (parameters don't match constraint system)
230
+ - FoomCash Mar 2026: one skipped CLI step left verifier broken from day one ($2.26M)
231
+ - "Default Settings" Mar 2026: two protocols, one skipped command
232
+
233
+ **Detection — grep/static**:
234
+ ```bash
235
+ # Look for hardcoded verifier keys that match test vectors
236
+ grep -rn "ptau\|powers_of_tau\|hermez\|setup\|ceremony" . --include="*.json" --include="*.ts" --include="*.js"
237
+
238
+ # Check if verificationKey.json matches production ceremony transcript
239
+ # Compare vk.alpha, vk.beta, vk.gamma against known test parameters:
240
+ # Hermez test ptau: alpha="0x0fd42..."
241
+
242
+ # Check for Groth16 vs production verifier deployment
243
+ grep -rn "Groth16Verifier\|PlonkVerifier\|verifyProof" contracts/ --include="*.sol"
244
+ ```
245
+
246
+ **Detection — Semgrep**:
247
+ ```yaml
248
+ rules:
249
+ - id: groth16-test-vk
250
+ pattern: |
251
+ alpha: "0x0fd42..." # Hermez test ceremony alpha
252
+ message: "ZK verifier may use test/dev trusted setup parameters"
253
+ severity: CRITICAL
254
+ ```
255
+
256
+ **Detection — Foundry**:
257
+ ```solidity
258
+ // Test: invalid proof must fail verification
259
+ function test_invalidProofRejected() external {
260
+ bytes memory fakeProof = abi.encode(uint256(1), uint256(2), uint256(3), uint256(4));
261
+ bool result = verifier.verifyProof(fakeProof, publicInputs);
262
+ assertFalse(result, "Fake proof accepted — ceremony may be broken");
263
+ }
264
+ ```
265
+
266
+ **Real examples**: FoomCash Mar 2026 ($2.26M), "Default Settings" protocols Mar 2026 (~$1M+), Tornado Cash (historical concern, not exploited due to community audit)
267
+
268
+ **Detection difficulty**: **Hard** — requires cryptographic knowledge and access to ceremony transcript; automated tools can only flag "test ptau" heuristics
269
+
270
+ ---
271
+
272
+ ### Pattern 6: Governance Flash Loan Attack
273
+
274
+ **Description**: Protocol allows governance token holders to vote on proposals, but lacks delay between acquiring voting power and using it. Attacker takes a flash loan of governance tokens, votes to pass a malicious proposal, and repays the loan — all in one transaction.
275
+
276
+ **Subtypes**:
277
+ - No vote-weight snapshot (reads current balance instead of historical)
278
+ - Proposal + vote + execute in single tx (no timelock)
279
+ - Borrow governance tokens, vote, repay (e.g., Compound-style delegation exploits)
280
+
281
+ **Detection — grep/static**:
282
+ ```bash
283
+ # Look for governance with current-block balance reads
284
+ grep -rn "balanceOf\|getVotes\|getPastVotes" contracts/ --include="*.sol"
285
+
286
+ # Missing snapshot / block number check
287
+ grep -rn "block.number\|getPastVotes\|ERC20Votes" contracts/ --include="*.sol"
288
+
289
+ # Missing timelock between proposal and execution
290
+ grep -rn "TimelockController\|Timelock\|votingDelay\|executionDelay" contracts/ --include="*.sol"
291
+ ```
292
+
293
+ **Detection — Slither**:
294
+ ```bash
295
+ slither . --detect tautology,incorrect-equality
296
+ # Custom: check if vote weight is read at proposal time vs current block
297
+ ```
298
+
299
+ **Detection — Foundry invariant**:
300
+ ```solidity
301
+ // Invariant: cannot propose AND vote AND execute in single transaction
302
+ function invariant_governanceCannotFlashLoanAttack() external {
303
+ vm.startPrank(attacker);
304
+ flashLoan(govToken, 1e24, ""); // get majority voting power
305
+ uint256 proposalId = governor.propose(...);
306
+ vm.expectRevert("Governor: vote not yet active");
307
+ governor.castVote(proposalId, 1); // must fail — no snapshot yet
308
+ }
309
+ ```
310
+
311
+ **Real examples**: Beanstalk Apr 2022 ($182M flash loan governance attack), Mango Markets Oct 2022 ($117M — governance + price manip), Build Finance DAO Feb 2022 (hostile takeover)
312
+
313
+ **Detection difficulty**: **Medium** — pattern is well-known; danger is in novel governance designs (e.g., optimistic voting, gauges)
314
+
315
+ ---
316
+
317
+ ### Pattern 7: Bridge Relay / Validator Compromise
318
+
319
+ **Description**: Cross-chain bridges rely on a set of validators or relayers to attest to cross-chain events. If the validator set is compromised (private keys stolen, threshold too low), attacker can authorize fraudulent withdrawals.
320
+
321
+ **Subtypes**:
322
+ - Low validator threshold (e.g., 5-of-9 with keys on hot servers)
323
+ - Single admin key controls bridge (IoTeX ioTube pattern)
324
+ - Compromised relayer submits fake deposit proofs
325
+ - Fake token price manipulation + bridge (Drift Trade Apr 2026)
326
+
327
+ **Detection — grep/static**:
328
+ ```bash
329
+ # Check validator threshold
330
+ grep -rn "threshold\|quorum\|minSignatures\|VALIDATOR_COUNT" contracts/ --include="*.sol"
331
+
332
+ # Check if bridge has emergency pause / guardian role
333
+ grep -rn "pause\|guardian\|emergencyStop" contracts/ --include="*.sol"
334
+
335
+ # Single-sig bridge admin
336
+ grep -rn "onlyOwner\|onlyAdmin" contracts/ --include="*.sol" | grep -i "bridge\|relay"
337
+ ```
338
+
339
+ **Real examples**: Drift Trade Apr 2026 ($285M), IoTeX ioTube Feb 2026 ($4.4M), Ronin Network Mar 2022 ($625M), Wormhole Feb 2022 ($320M), Nomad Aug 2022 ($190M)
340
+
341
+ **Detection difficulty**: **Easy to flag low threshold / single admin** / **Hard to prevent off-chain compromise**
342
+
343
+ ---
344
+
345
+ ### Pattern 8: Incorrect Token Accounting / Share Rounding
346
+
347
+ **Description**: Subtle errors in how a protocol tracks user shares, balances, or claimable amounts. Often manifests as rounding errors in integer arithmetic that accumulate or can be triggered in a single large transaction.
348
+
349
+ **Subtypes**:
350
+ - Division before multiplication (truncation in wrong order)
351
+ - Unchecked balance after fee-on-transfer token deposit
352
+ - `totalSupply()` doesn't account for locked/burned shares
353
+ - `GoonFi` "mispricing arbitrage" Mar 2026 ($254K)
354
+
355
+ **Detection — grep/static**:
356
+ ```bash
357
+ # Detect division before multiplication pattern
358
+ grep -rn "/" contracts/ --include="*.sol" -A 1 | grep "*"
359
+ # Better: use Slither
360
+
361
+ # Fee-on-transfer token not accounted for
362
+ grep -rn "transferFrom\|safeTransferFrom" contracts/ --include="*.sol"
363
+ # If no before/after balanceOf check: flag as potential FoT issue
364
+ ```
365
+
366
+ **Detection — Slither**:
367
+ ```bash
368
+ slither . --detect divide-before-multiply,incorrect-equality,tautology
369
+ ```
370
+
371
+ **Detection difficulty**: **Medium** — Slither catches divide-before-multiply; fee-on-transfer and share accounting bugs require semantic understanding
372
+
373
+ ---
374
+
375
+ ## Summary: Automation Coverage by Vuln Class
376
+
377
+ | Pattern | Slither | Semgrep | Foundry Fuzzing | LLM Review | Priority |
378
+ |---|---|---|---|---|---|
379
+ | Oracle Price Manipulation | Partial | Custom rule | High (property tests) | High | **CRITICAL** |
380
+ | Flash Loan Share Inflation | Yes (ERC-4626) | Custom rule | High | Medium | **CRITICAL** |
381
+ | Reentrancy (classic) | Yes | Yes | Medium | Low | HIGH |
382
+ | Reentrancy (cross-func/read-only) | Partial | No | High | High | HIGH |
383
+ | Private Key / Admin Compromise | Centralization flag | No | N/A (off-chain) | High | HIGH |
384
+ | ZK Trusted Setup Failure | No | Custom rule | Partial | High | CRITICAL (emerging) |
385
+ | Governance Flash Loan | No | Custom rule | High | High | HIGH |
386
+ | Bridge Validator Threshold | No | Partial | No | High | HIGH |
387
+ | Token Accounting / Rounding | Yes | Partial | High | Medium | MEDIUM |
388
+
389
+ ---
390
+
391
+ ## Key Takeaways for Automated Scanning
392
+
393
+ 1. **Audited protocols still get rekt** — Venus rekt IV, Aave rekt (both audited). Static analysis must look for *variant* patterns, not just textbook examples.
394
+
395
+ 2. **Bug bounty ceilings are systemically too low** — FoomCash had a "code is law" $320K bounty vs $2.26M loss. Immunefi max bounties ($1M-$3M) cover only Tier-1 protocols; most protocols have no bounty or low ceilings.
396
+
397
+ 3. **AI-generated code is a new attack surface** — Moonwell Feb 2026 was "co-authored by Claude Opus 4.6." Standard audit tooling wasn't adapted for AI-generated contract patterns.
398
+
399
+ 4. **ZK vulnerabilities are emerging** — Two protocols in one week (Mar 2026) exploited via trusted setup failures. Tooling gap: no Slither detector, no standard CI check.
400
+
401
+ 5. **Oracle manipulation is perennial** — Every year, multiple protocols lose $5M–$300M to oracle manipulation in forms the previous year's patches didn't cover.