web3crit-scanner 7.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.
Files changed (42) hide show
  1. package/README.md +685 -0
  2. package/bin/web3crit +10 -0
  3. package/package.json +59 -0
  4. package/src/analyzers/control-flow.js +256 -0
  5. package/src/analyzers/data-flow.js +720 -0
  6. package/src/analyzers/exploit-chain.js +751 -0
  7. package/src/analyzers/immunefi-classifier.js +515 -0
  8. package/src/analyzers/poc-validator.js +396 -0
  9. package/src/analyzers/solodit-enricher.js +1122 -0
  10. package/src/cli.js +546 -0
  11. package/src/detectors/access-control-enhanced.js +458 -0
  12. package/src/detectors/base-detector.js +213 -0
  13. package/src/detectors/callback-reentrancy.js +362 -0
  14. package/src/detectors/cross-contract-reentrancy.js +697 -0
  15. package/src/detectors/delegatecall.js +167 -0
  16. package/src/detectors/deprecated-functions.js +62 -0
  17. package/src/detectors/flash-loan.js +408 -0
  18. package/src/detectors/frontrunning.js +553 -0
  19. package/src/detectors/gas-griefing.js +701 -0
  20. package/src/detectors/governance-attacks.js +366 -0
  21. package/src/detectors/integer-overflow.js +487 -0
  22. package/src/detectors/oracle-manipulation.js +524 -0
  23. package/src/detectors/permit-exploits.js +368 -0
  24. package/src/detectors/precision-loss.js +408 -0
  25. package/src/detectors/price-manipulation-advanced.js +548 -0
  26. package/src/detectors/proxy-vulnerabilities.js +651 -0
  27. package/src/detectors/readonly-reentrancy.js +473 -0
  28. package/src/detectors/rebasing-token-vault.js +416 -0
  29. package/src/detectors/reentrancy-enhanced.js +359 -0
  30. package/src/detectors/selfdestruct.js +259 -0
  31. package/src/detectors/share-manipulation.js +412 -0
  32. package/src/detectors/signature-replay.js +409 -0
  33. package/src/detectors/storage-collision.js +446 -0
  34. package/src/detectors/timestamp-dependence.js +494 -0
  35. package/src/detectors/toctou.js +427 -0
  36. package/src/detectors/token-standard-compliance.js +465 -0
  37. package/src/detectors/unchecked-call.js +214 -0
  38. package/src/detectors/vault-inflation.js +421 -0
  39. package/src/index.js +42 -0
  40. package/src/package-lock.json +2874 -0
  41. package/src/package.json +39 -0
  42. package/src/scanner-enhanced.js +816 -0
@@ -0,0 +1,548 @@
1
+ const BaseDetector = require('./base-detector');
2
+
3
+ /**
4
+ * Advanced Price Manipulation Detector
5
+ *
6
+ * Detects sophisticated price manipulation vectors in high-TVL DeFi:
7
+ * - Multi-block price manipulation (sustained manipulation)
8
+ * - Cross-pool arbitrage exploitation
9
+ * - Curve/Balancer-specific vulnerabilities
10
+ * - Liquidation price manipulation
11
+ * - LP token price manipulation
12
+ *
13
+ * Based on real Immunefi bounties:
14
+ * - Cream Finance ($130M) - Oracle manipulation
15
+ * - Harvest Finance ($34M) - USDC/USDT pool manipulation
16
+ * - Warp Finance ($7.7M) - LP token pricing
17
+ * - Inverse Finance ($15M) - Price oracle attack
18
+ *
19
+ * Immunefi Critical: Direct theft via price manipulation
20
+ */
21
+ class AdvancedPriceManipulationDetector extends BaseDetector {
22
+ constructor() {
23
+ super(
24
+ 'Advanced Price Manipulation',
25
+ 'Detects sophisticated price manipulation vulnerabilities in DeFi',
26
+ 'CRITICAL'
27
+ );
28
+ this.currentContract = null;
29
+ this.currentFunction = null;
30
+ this.priceReads = [];
31
+ this.valueOperations = [];
32
+ this.poolInteractions = [];
33
+ }
34
+
35
+ async detect(ast, sourceCode, fileName, cfg, dataFlow) {
36
+ this.findings = [];
37
+ this.ast = ast;
38
+ this.sourceCode = sourceCode;
39
+ this.fileName = fileName;
40
+ this.sourceLines = sourceCode.split('\n');
41
+ this.cfg = cfg;
42
+ this.dataFlow = dataFlow;
43
+ this.priceReads = [];
44
+ this.valueOperations = [];
45
+ this.poolInteractions = [];
46
+
47
+ // Detect protocol patterns
48
+ this.detectProtocolPatterns();
49
+
50
+ this.traverse(ast);
51
+ this.analyzePriceManipulationVectors();
52
+
53
+ return this.findings;
54
+ }
55
+
56
+ /**
57
+ * Detect which DeFi protocols are being used
58
+ */
59
+ detectProtocolPatterns() {
60
+ const code = this.sourceCode;
61
+
62
+ this.protocols = {
63
+ uniswapV2: /IUniswapV2|UniswapV2|getReserves|addLiquidity|removeLiquidity/i.test(code),
64
+ uniswapV3: /IUniswapV3|UniswapV3|slot0|sqrtPriceX96|observe/i.test(code),
65
+ curve: /ICurve|CurvePool|get_dy|get_virtual_price|exchange/i.test(code),
66
+ balancer: /IBalancer|BalancerVault|getPoolTokens|flashLoan/i.test(code),
67
+ aave: /IAave|LendingPool|getReserveData|getUserAccountData/i.test(code),
68
+ compound: /IComptroller|ICToken|getAccountLiquidity|exchangeRate/i.test(code),
69
+ chainlink: /AggregatorV3|latestRoundData|latestAnswer/i.test(code),
70
+ };
71
+
72
+ this.isLendingProtocol = this.protocols.aave || this.protocols.compound ||
73
+ /borrow|liquidat|collateral|healthFactor/i.test(code);
74
+
75
+ this.isAMM = this.protocols.uniswapV2 || this.protocols.uniswapV3 ||
76
+ this.protocols.curve || this.protocols.balancer;
77
+ }
78
+
79
+ visitContractDefinition(node) {
80
+ this.currentContract = node.name;
81
+ }
82
+
83
+ visitFunctionDefinition(node) {
84
+ this.currentFunction = node.name || 'constructor';
85
+
86
+ if (!node.body) return;
87
+ if (node.visibility === 'private' || node.visibility === 'internal') return;
88
+
89
+ const funcCode = this.getCodeSnippet(node.loc);
90
+ const funcName = (node.name || '').toLowerCase();
91
+
92
+ // Detect LP token pricing issues
93
+ this.detectLPTokenPricing(funcCode, node);
94
+
95
+ // Detect Curve-specific vulnerabilities
96
+ this.detectCurveVulnerabilities(funcCode, node);
97
+
98
+ // Detect Balancer-specific vulnerabilities
99
+ this.detectBalancerVulnerabilities(funcCode, node);
100
+
101
+ // Detect liquidation price manipulation
102
+ this.detectLiquidationManipulation(funcCode, node);
103
+
104
+ // Detect cross-pool price reliance
105
+ this.detectCrossPoolReliance(funcCode, node);
106
+
107
+ // Detect same-block price usage
108
+ this.detectSameBlockPricing(funcCode, node);
109
+ }
110
+
111
+ /**
112
+ * Detect LP token pricing vulnerabilities
113
+ * Attack: Manipulate reserves → inflate/deflate LP token price → exploit
114
+ */
115
+ detectLPTokenPricing(funcCode, node) {
116
+ // LP token value = sqrt(reserve0 * reserve1) * 2 / totalSupply
117
+ // Or: LP token value = (reserve0/supply + reserve1/supply) * prices
118
+ const lpPricingPatterns = [
119
+ /getReserves.*totalSupply|totalSupply.*getReserves/i,
120
+ /sqrt\s*\(.*reserve.*reserve/i,
121
+ /lpToken.*price|price.*lpToken/i,
122
+ /underlying.*lp|lp.*underlying/i,
123
+ ];
124
+
125
+ const hasLPPricing = lpPricingPatterns.some(p => p.test(funcCode));
126
+
127
+ if (hasLPPricing) {
128
+ // Check if price is used in value operations
129
+ const usedForValue = /collateral|borrow|liquidat|mint.*share|withdraw/i.test(funcCode);
130
+
131
+ if (usedForValue) {
132
+ // Check for manipulation protection
133
+ const hasProtection = /twap|average|delay|snapshot|checkpoint/i.test(funcCode);
134
+
135
+ if (!hasProtection) {
136
+ this.addFinding({
137
+ title: 'LP Token Price Manipulation Vulnerability',
138
+ description: `Function '${this.currentFunction}' uses LP token pricing for value operations without manipulation protection.\n\n` +
139
+ `Attack (Warp Finance style):\n` +
140
+ `1. Flash loan large amount of underlying tokens\n` +
141
+ `2. Add to pool, manipulating reserves\n` +
142
+ `3. LP token price artificially inflated\n` +
143
+ `4. Use overvalued LP as collateral or calculate shares\n` +
144
+ `5. Extract value (borrow, mint shares, etc.)\n` +
145
+ `6. Remove liquidity, repay flash loan\n\n` +
146
+ `Real-world exploits:\n` +
147
+ `- Warp Finance: $7.7M stolen\n` +
148
+ `- Value DeFi: $6M stolen\n` +
149
+ `- Cheese Bank: $3.3M stolen`,
150
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
151
+ line: node.loc?.start?.line || 0,
152
+ code: funcCode.substring(0, 400),
153
+ severity: 'CRITICAL',
154
+ confidence: 'HIGH',
155
+ exploitable: true,
156
+ exploitabilityScore: 95,
157
+ attackVector: 'lp-token-manipulation',
158
+ recommendation: `1. Use TWAP for LP token pricing\n` +
159
+ `2. Use fair LP pricing: 2 * sqrt(r0 * r1) / supply (Alpha Homora formula)\n` +
160
+ `3. Add minimum liquidity checks\n` +
161
+ `4. Verify reserves haven't changed in same block\n` +
162
+ `5. Consider Chainlink LP token price feeds`,
163
+ references: [
164
+ 'https://cmichel.io/pricing-lp-tokens/',
165
+ 'https://blog.alphafinance.io/fair-lp-token-pricing/'
166
+ ],
167
+ foundryPoC: this.generateLPManipulationPoC()
168
+ });
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Detect Curve-specific vulnerabilities
176
+ */
177
+ detectCurveVulnerabilities(funcCode, node) {
178
+ if (!this.protocols.curve) return;
179
+
180
+ // Curve virtual price manipulation
181
+ const usesVirtualPrice = /get_virtual_price|virtualPrice/i.test(funcCode);
182
+
183
+ if (usesVirtualPrice) {
184
+ // Check if used during reentrancy-susceptible operations
185
+ const hasReentrancyRisk = /\.call\s*\{|withdraw|remove_liquidity/i.test(funcCode);
186
+
187
+ if (hasReentrancyRisk) {
188
+ this.addFinding({
189
+ title: 'Curve Read-Only Reentrancy via virtual_price',
190
+ description: `Function '${this.currentFunction}' reads Curve virtual_price which is vulnerable to read-only reentrancy.\n\n` +
191
+ `Attack (2022 Curve/Vyper exploits):\n` +
192
+ `1. Call remove_liquidity on Curve pool\n` +
193
+ `2. During callback (ETH transfer), reenter victim contract\n` +
194
+ `3. Victim reads stale virtual_price (not yet updated)\n` +
195
+ `4. Virtual price appears higher than actual\n` +
196
+ `5. Attacker profits from price discrepancy\n\n` +
197
+ `This affected multiple protocols integrating Curve.`,
198
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
199
+ line: node.loc?.start?.line || 0,
200
+ code: funcCode.substring(0, 300),
201
+ severity: 'CRITICAL',
202
+ confidence: 'HIGH',
203
+ exploitable: true,
204
+ exploitabilityScore: 90,
205
+ attackVector: 'curve-readonly-reentrancy',
206
+ recommendation: `1. Add reentrancy guard that covers virtual_price reads\n` +
207
+ `2. Use Curve's reentrancy lock: raw_call(pool, method_id("claim_admin_fees()"))\n` +
208
+ `3. Cache virtual_price at start of transaction\n` +
209
+ `4. Don't use virtual_price for immediate pricing decisions`,
210
+ references: [
211
+ 'https://chainsecurity.com/heartbreak-curve-lp-oracle-manipulation/'
212
+ ]
213
+ });
214
+ }
215
+ }
216
+
217
+ // Curve get_dy spot price
218
+ const usesGetDy = /get_dy\s*\(|calc_token_amount/i.test(funcCode);
219
+
220
+ if (usesGetDy) {
221
+ const usedForValue = /collateral|borrow|mint|price/i.test(funcCode);
222
+
223
+ if (usedForValue) {
224
+ this.addFinding({
225
+ title: 'Curve Spot Price (get_dy) Used for Valuation',
226
+ description: `Function '${this.currentFunction}' uses Curve's get_dy for pricing, which returns spot price and is manipulable.\n\n` +
227
+ `Issue: get_dy returns current exchange rate, which can be manipulated by:\n` +
228
+ `1. Large swaps that move the curve\n` +
229
+ `2. Flash loans providing temporary liquidity\n` +
230
+ `3. Imbalanced pool additions\n\n` +
231
+ `For valuation, use oracle prices or time-weighted calculations.`,
232
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
233
+ line: node.loc?.start?.line || 0,
234
+ code: funcCode.substring(0, 200),
235
+ severity: 'HIGH',
236
+ confidence: 'MEDIUM',
237
+ exploitable: true,
238
+ exploitabilityScore: 75,
239
+ attackVector: 'curve-spot-price',
240
+ recommendation: `1. Use Chainlink price feeds for token valuation\n` +
241
+ `2. Implement TWAP over Curve trades\n` +
242
+ `3. Add slippage protection for swaps`
243
+ });
244
+ }
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Detect Balancer-specific vulnerabilities
250
+ */
251
+ detectBalancerVulnerabilities(funcCode, node) {
252
+ if (!this.protocols.balancer) return;
253
+
254
+ // Balancer flash loan + pool manipulation
255
+ const hasFlashLoan = /flashLoan|onFlashLoan|receiveFlashLoan/i.test(funcCode);
256
+ const hasPoolOps = /getPoolTokens|joinPool|exitPool/i.test(funcCode);
257
+
258
+ if (hasFlashLoan && hasPoolOps) {
259
+ this.addFinding({
260
+ title: 'Balancer Flash Loan Pool Manipulation Risk',
261
+ description: `Function '${this.currentFunction}' combines Balancer flash loans with pool operations.\n\n` +
262
+ `Risk: Balancer flash loans are free (no fee for returning same block), enabling:\n` +
263
+ `1. Borrow all pool tokens via flash loan\n` +
264
+ `2. Manipulate pool balances/prices\n` +
265
+ `3. Execute exploit during manipulation\n` +
266
+ `4. Return tokens\n\n` +
267
+ `Ensure price reads don't occur during flashloan-susceptible states.`,
268
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
269
+ line: node.loc?.start?.line || 0,
270
+ code: funcCode.substring(0, 300),
271
+ severity: 'HIGH',
272
+ confidence: 'MEDIUM',
273
+ exploitable: true,
274
+ exploitabilityScore: 70,
275
+ attackVector: 'balancer-flash-manipulation',
276
+ recommendation: `1. Don't read pool prices during flash loan callbacks\n` +
277
+ `2. Verify pool state hasn't changed unexpectedly\n` +
278
+ `3. Use external oracles for pricing\n` +
279
+ `4. Add reentrancy protection`
280
+ });
281
+ }
282
+
283
+ // Balancer getRate for valuation
284
+ const usesGetRate = /getRate\s*\(|getRateProviders/i.test(funcCode);
285
+
286
+ if (usesGetRate) {
287
+ const usedForCollateral = /collateral|borrow|health|liquidat/i.test(funcCode);
288
+
289
+ if (usedForCollateral) {
290
+ this.addFinding({
291
+ title: 'Balancer Rate Provider Used for Collateral Valuation',
292
+ description: `Function uses Balancer rate provider for collateral valuation.\n\n` +
293
+ `Risk: Rate providers can be manipulated or become stale.\n` +
294
+ `Some rate providers read from pools that can be manipulated.`,
295
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
296
+ line: node.loc?.start?.line || 0,
297
+ severity: 'MEDIUM',
298
+ confidence: 'MEDIUM',
299
+ exploitable: true,
300
+ exploitabilityScore: 60,
301
+ attackVector: 'balancer-rate-manipulation',
302
+ recommendation: `1. Verify rate provider source is manipulation-resistant\n` +
303
+ `2. Add sanity bounds on rate changes\n` +
304
+ `3. Consider backup oracles`
305
+ });
306
+ }
307
+ }
308
+ }
309
+
310
+ /**
311
+ * Detect liquidation price manipulation
312
+ */
313
+ detectLiquidationManipulation(funcCode, node) {
314
+ if (!this.isLendingProtocol) return;
315
+
316
+ const funcName = (node.name || '').toLowerCase();
317
+
318
+ if (/liquidat/i.test(funcName) || /liquidat/i.test(funcCode)) {
319
+ // Check if liquidation uses spot prices
320
+ const usesSpotPrice = /getReserves|slot0|get_dy|balanceOf.*balanceOf/i.test(funcCode);
321
+ const usesOracle = /latestRoundData|getAssetPrice|oracle/i.test(funcCode);
322
+
323
+ if (usesSpotPrice && !usesOracle) {
324
+ this.addFinding({
325
+ title: 'Liquidation Uses Manipulable Spot Price',
326
+ description: `Liquidation function '${this.currentFunction}' uses spot prices instead of oracles.\n\n` +
327
+ `Attack (Inverse Finance style):\n` +
328
+ `1. Open leveraged position at normal prices\n` +
329
+ `2. Flash loan to manipulate spot price downward\n` +
330
+ `3. Trigger liquidation of victims (including self-liquidation for profit)\n` +
331
+ `4. Restore price, repay flash loan\n` +
332
+ `5. Profit from liquidation bonus\n\n` +
333
+ `Inverse Finance lost $15M to this attack pattern.`,
334
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
335
+ line: node.loc?.start?.line || 0,
336
+ code: funcCode.substring(0, 300),
337
+ severity: 'CRITICAL',
338
+ confidence: 'HIGH',
339
+ exploitable: true,
340
+ exploitabilityScore: 95,
341
+ attackVector: 'liquidation-manipulation',
342
+ recommendation: `1. Use Chainlink oracles for liquidation prices\n` +
343
+ `2. Add circuit breakers for rapid price changes\n` +
344
+ `3. Implement time-delayed liquidations\n` +
345
+ `4. Use TWAP as fallback\n` +
346
+ `5. Add maximum liquidation amounts per block`,
347
+ references: [
348
+ 'https://rekt.news/inverse-finance-rekt/'
349
+ ]
350
+ });
351
+ }
352
+
353
+ // Check for same-block liquidation
354
+ const allowsSameBlockLiquidation = !/blockNumber.*!=|lastUpdate.*<|delay/i.test(funcCode);
355
+
356
+ if (allowsSameBlockLiquidation && usesOracle) {
357
+ this.addFinding({
358
+ title: 'Same-Block Liquidation Allowed',
359
+ description: `Liquidation in '${this.currentFunction}' can occur in the same block as position changes.\n\n` +
360
+ `Risk:\n` +
361
+ `1. Attacker manipulates oracle in block N\n` +
362
+ `2. Opens position + liquidates victim in same block\n` +
363
+ `3. Oracle manipulation is never observed externally\n\n` +
364
+ `This enables atomic MEV-style liquidation attacks.`,
365
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
366
+ line: node.loc?.start?.line || 0,
367
+ severity: 'HIGH',
368
+ confidence: 'MEDIUM',
369
+ exploitable: true,
370
+ exploitabilityScore: 70,
371
+ attackVector: 'same-block-liquidation',
372
+ recommendation: `1. Require minimum time between position change and liquidation\n` +
373
+ `2. Use block.number checks to prevent same-block liquidation\n` +
374
+ `3. Implement gradual liquidation with time delays`
375
+ });
376
+ }
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Detect cross-pool price reliance
382
+ */
383
+ detectCrossPoolReliance(funcCode, node) {
384
+ // Multiple pool reads in same function
385
+ const poolPatterns = [
386
+ /getReserves/gi,
387
+ /slot0/gi,
388
+ /get_dy/gi,
389
+ /getPoolTokens/gi,
390
+ ];
391
+
392
+ let poolReadCount = 0;
393
+ for (const pattern of poolPatterns) {
394
+ const matches = funcCode.match(pattern);
395
+ if (matches) poolReadCount += matches.length;
396
+ }
397
+
398
+ if (poolReadCount >= 2) {
399
+ // Multiple pools read - check for arbitrage/manipulation risk
400
+ this.addFinding({
401
+ title: 'Cross-Pool Price Dependency Detected',
402
+ description: `Function '${this.currentFunction}' reads prices from multiple pools.\n\n` +
403
+ `Risk: Cross-pool manipulation attack:\n` +
404
+ `1. Attacker manipulates Pool A price up\n` +
405
+ `2. Contract reads Pool A price for valuation\n` +
406
+ `3. Attacker uses overvalued position\n` +
407
+ `4. Attacker manipulates Pool B for arbitrage profit\n\n` +
408
+ `This creates complex manipulation opportunities.`,
409
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
410
+ line: node.loc?.start?.line || 0,
411
+ code: funcCode.substring(0, 300),
412
+ severity: 'HIGH',
413
+ confidence: 'MEDIUM',
414
+ exploitable: true,
415
+ exploitabilityScore: 65,
416
+ attackVector: 'cross-pool-manipulation',
417
+ recommendation: `1. Use same oracle source for related assets\n` +
418
+ `2. Add cross-pool price deviation checks\n` +
419
+ `3. Implement maximum price impact limits\n` +
420
+ `4. Consider circuit breakers for extreme deviations`
421
+ });
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Detect same-block price usage issues
427
+ */
428
+ detectSameBlockPricing(funcCode, node) {
429
+ // Check if price is read and used without block delay
430
+ const readsPriceOrReserves = /getReserves|slot0|latestRoundData|getAssetPrice|balanceOf/i.test(funcCode);
431
+ const hasValueOperation = /mint|burn|swap|borrow|withdraw|deposit/i.test(funcCode);
432
+ const hasBlockCheck = /block\.number\s*!=|lastBlock|blockDelay|_lastUpdateBlock/i.test(funcCode);
433
+
434
+ if (readsPriceOrReserves && hasValueOperation && !hasBlockCheck) {
435
+ // Check if it's a swap function (expected behavior)
436
+ const funcName = (node.name || '').toLowerCase();
437
+ if (/^swap|^exchange/i.test(funcName)) {
438
+ return; // Swaps need current price
439
+ }
440
+
441
+ this.addFinding({
442
+ title: 'Price Used Without Block Delay Protection',
443
+ description: `Function '${this.currentFunction}' reads prices and performs value operations in potentially same block.\n\n` +
444
+ `Risk: Atomic manipulation attack:\n` +
445
+ `1. Manipulate price in transaction 1 of block\n` +
446
+ `2. Call vulnerable function in transaction 2\n` +
447
+ `3. Restore price in transaction 3\n` +
448
+ `All in same block, appearing atomic to external observers.`,
449
+ location: `Contract: ${this.currentContract}, Function: ${this.currentFunction}`,
450
+ line: node.loc?.start?.line || 0,
451
+ severity: 'MEDIUM',
452
+ confidence: 'LOW',
453
+ exploitable: true,
454
+ exploitabilityScore: 55,
455
+ attackVector: 'same-block-pricing',
456
+ recommendation: `1. Track last update block for price-sensitive operations\n` +
457
+ `2. Require price to be at least 1 block old\n` +
458
+ `3. Use commit-reveal pattern for large operations`
459
+ });
460
+ }
461
+ }
462
+
463
+ /**
464
+ * Analyze collected price manipulation vectors
465
+ */
466
+ analyzePriceManipulationVectors() {
467
+ // Check for dangerous protocol combinations
468
+ if (this.protocols.uniswapV2 && this.isLendingProtocol) {
469
+ // UniV2 spot price + lending = classic attack surface
470
+ const hasOracleProtection = this.protocols.chainlink ||
471
+ /twap|timeWeighted|average/i.test(this.sourceCode);
472
+
473
+ if (!hasOracleProtection) {
474
+ this.addFinding({
475
+ title: 'Lending Protocol Uses Uniswap V2 Spot Prices',
476
+ description: `Contract combines lending functionality with Uniswap V2 price reads without oracle protection.\n\n` +
477
+ `This is the classic attack pattern used in:\n` +
478
+ `- bZx ($8M)\n` +
479
+ `- Harvest Finance ($34M)\n` +
480
+ `- Cream Finance ($130M)\n\n` +
481
+ `UniV2 reserves can be manipulated within a single transaction via flash loans.`,
482
+ location: `Contract: ${this.currentContract}`,
483
+ line: 1,
484
+ severity: 'CRITICAL',
485
+ confidence: 'HIGH',
486
+ exploitable: true,
487
+ exploitabilityScore: 95,
488
+ attackVector: 'univ2-lending-manipulation',
489
+ recommendation: `CRITICAL: Never use UniV2 spot prices for lending:\n` +
490
+ `1. Use Chainlink price feeds\n` +
491
+ `2. Implement UniV2 TWAP (30+ minute window)\n` +
492
+ `3. Add price deviation circuit breakers\n` +
493
+ `4. Consider using UniV3 TWAP`,
494
+ references: [
495
+ 'https://samczsun.com/taking-undercollateralized-loans-for-fun-and-for-profit/'
496
+ ]
497
+ });
498
+ }
499
+ }
500
+ }
501
+
502
+ generateLPManipulationPoC() {
503
+ return `// SPDX-License-Identifier: MIT
504
+ pragma solidity ^0.8.0;
505
+
506
+ import "forge-std/Test.sol";
507
+
508
+ /**
509
+ * PoC: LP Token Price Manipulation (Warp Finance style)
510
+ */
511
+ contract LPManipulationExploit is Test {
512
+ // ILendingProtocol lending;
513
+ // IUniswapV2Pair lpToken;
514
+ // IERC20 token0;
515
+ // IERC20 token1;
516
+
517
+ function testLPManipulation() public {
518
+ // Setup: Get flash loan for manipulation capital
519
+
520
+ // Step 1: Add massive liquidity to inflate LP price
521
+ // uint256 loanAmount = 10_000_000e18;
522
+ // token0.approve(address(router), loanAmount);
523
+ // token1.approve(address(router), loanAmount);
524
+ // router.addLiquidity(...);
525
+
526
+ // LP token price is now artificially high
527
+
528
+ // Step 2: Deposit inflated LP as collateral
529
+ // lpToken.approve(address(lending), lpBalance);
530
+ // lending.depositCollateral(address(lpToken), lpBalance);
531
+
532
+ // Step 3: Borrow against inflated collateral
533
+ // uint256 maxBorrow = lending.getMaxBorrow(address(this));
534
+ // lending.borrow(maxBorrow);
535
+
536
+ // Step 4: Remove liquidity (deflates LP price)
537
+ // router.removeLiquidity(...);
538
+
539
+ // Step 5: Repay flash loan
540
+ // Profit = borrowed amount - flash loan fee
541
+
542
+ // Victim: Lending protocol is now undercollateralized
543
+ }
544
+ }`;
545
+ }
546
+ }
547
+
548
+ module.exports = AdvancedPriceManipulationDetector;