Skip to main content

economic-attack

Auto-loaded by flashloan-auditor and defi-auditor agents during Phase 2. Provides detection patterns for: spot price manipulation, oracle staleness, short TWAP, donation attacks, slippage, flash loan governance. Core artifact: Price Flow Map.

설치로 이동

소스 정보

저장소
BitterSecurity/Vigilo
최근 소스 활동
2026년 1월 26일 12:30
감지된 SKILL.md 언어
영어
스타
66
포크
17

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
economic-attack
description
Auto-loaded by flashloan-auditor and defi-auditor agents during Phase 2. Provides detection patterns for: spot price manipulation, oracle staleness, short TWAP, donation attacks, slippage, flash loan governance. Core artifact: Price Flow Map.
user-invocable
false
# Economic Attack Vulnerability Analysis **2025 Statistics**: Flash loans = **83.3% of DeFi exploits**, Oracle manipulation = **+31% YoY**, Price manipulation = **34.3% of MUBs**. --- ## Attacker Mindset: Infinite Capital **CRITICAL**: With flash loans, attackers have **INFINITE CAPITAL** for one transaction. ``` +------------------------------------------------------------------+ | SINGLE ATOMIC TRANSACTION | +------------------------------------------------------------------+ | 1. BORROW | Flash loan $100M+ from Aave/dYdX (cost: 0.09%) | | 2. MANIPULATE| Change any on-chain value (price, balance, ratio) | | 3. EXPLOIT | Call target function with manipulated state | | 4. PROFIT | Extract value (mint, borrow, swap at bad rate) | | 5. REPAY | Return flash loan + fee | | 6. KEEP | Attacker keeps profit, victims lose funds | +------------------------------------------------------------------+ ``` **Key insight**: If ANY step fails, entire transaction reverts. Attacker loses only gas (~$50). This means attackers can try complex attacks with zero risk. --- ## Why Economic Attacks Happen (Root Causes) ### Root Cause 1: Single Source Price Dependency Protocol trusts ONE price source that attacker can manipulate. ```solidity // VULNERABLE: Single DEX pool as price source function getPrice() public view returns (uint256) { (uint112 r0, uint112 r1,) = uniswapPair.getReserves(); return uint256(r1) * 1e18 / uint256(r0); // @audit Flash loan can drain r0 } ``` **Attacker's view**: "I can move this price with enough capital. Flash loan gives me that capital." ### Root Cause 2: Spot Price Trust Using current-moment values instead of time-averaged values. ```solidity // VULNERABLE: Current block's reserves price = reserves[1] / reserves[0]; // @audit Reflects THIS transaction's state // What attacker sees: // 1. Swap to move reserves // 2. Read manipulated price // 3. Exploit protocol // 4. Swap back // All in one tx! ``` **Detection**: Any `getReserves()`, `slot0()`, `balanceOf()` used for pricing is suspect. ### Root Cause 3: Staleness Blindness Oracle price could be hours or days old, but protocol uses it anyway. ```solidity // VULNERABLE: No staleness check (, int256 price,,,) = chainlinkFeed.latestRoundData(); return uint256(price); // @audit Could be from yesterday! // Attacker's opportunity: // - Wait for oracle to become stale during volatility // - Real price moved 20%, oracle still shows old price // - Liquidate users at wrong price, or borrow too much ``` **Detection**: `latestRoundData()` without checking `updatedAt` timestamp. ### Root Cause 4: Composability Trust Protocol blindly trusts external protocol's reported values. ```solidity // VULNERABLE: Trusting external vault's totalAssets function getCollateralValue(address user) view returns (uint256) { uint256 shares = externalVault.balanceOf(user); uint256 pricePerShare = externalVault.totalAssets() / externalVault.totalSupply(); return shares * pricePerShare; // @audit totalAssets can be donated to! } ``` **Attacker's view**: "I can donate to that vault and inflate pricePerShare, then borrow against it." --- ## The Price Flow Map (Core Artifact) Trace how prices flow through the system: ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Price Source │ ──► │ Reading Function │ ──► │ Critical Decision│ │ (Oracle/DEX) │ │ (getPrice, etc) │ │ (liquidate,mint)│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ ▼ ▼ Manipulable? Value Transfer - Flash loan? (funds move) - Donation? - Time window? ``` Document each price dependency: | Function | Price Source | Manipulable? | Impact if Manipulated | |----------|--------------|--------------|----------------------| | liquidate() | Chainlink ETH/USD | Staleness only | Unfair liquidations | | borrow() | Uniswap reserves | Flash loan | Undercollateralized borrow | | mint() | vault.totalAssets() | Donation | Steal other users' deposits | --- ## Detection Patterns ### Pattern 1: Spot Price Dependency (Most Critical) **Root Cause**: Single Source + Spot Price Trust ```solidity // VULNERABLE: Direct reserve ratio function getTokenPrice() public view returns (uint256) { (uint112 r0, uint112 r1,) = pair.getReserves(); return uint256(r1) * 1e18 / uint256(r0); // @audit Instant manipulation } ``` **Attack Flow**: 1. Flash loan large amount of token0 2. Swap to drain token0 from pool → price spikes 3. Call victim function that reads this price 4. Profit at inflated price 5. Swap back, repay flash loan **Search Queries**: ``` Grep("getReserves|slot0|observe", glob="**/*.sol") Grep("reserve0|reserve1|liquidity", glob="**/*.sol") ``` **Verification Questions**: - Is this price used for critical decisions? - Can flash loan move this price significantly? - Is there enough liquidity to resist manipulation? ### Pattern 2: Oracle Staleness **Root Cause**: Staleness Blindness ```solidity // VULNERABLE: No freshness validation function getPrice() external view returns (uint256) { (, int256 price,,,) = priceFeed.latestRoundData(); return uint256(price); // @audit Could be stale! } // Attack opportunity: // During high volatility, oracle updates lag // Real ETH = $3000, Oracle still says $2500 // Attacker borrows at $2500 collateral value // Immediately has undercollateralized position ``` **Search Queries**: ``` Grep("latestRoundData|latestAnswer", glob="**/*.sol") Grep("updatedAt|answeredInRound", glob="**/*.sol") ``` **Verification Questions**: - Is `updatedAt` checked against a max staleness? - What's the heartbeat of this oracle? - What happens during oracle downtime? ### Pattern 3: Short TWAP Window **Root Cause**: Insufficient time averaging ```solidity // VULNERABLE: 1 minute TWAP uint32[] memory secondsAgos = new uint32[](2); secondsAgos[0] = 60; // @audit Only 60 seconds! secondsAgos[1] = 0; (int56[] memory tickCumulatives,) = pool.observe(secondsAgos); ``` **Attacker's view**: "I can maintain manipulated price for 60 seconds across multiple blocks if I'm a validator, or use multiple flash loans." **Safe TWAP windows**: - Minimum: 30 minutes (1800 seconds) - Recommended: 1-4 hours for high-value decisions **Search Queries**: ``` Grep("observe|consult|TWAP|twap", glob="**/*.sol") Grep("secondsAgo|period|window", glob="**/*.sol") ``` ### Pattern 4: Donation Attack / Share Inflation **Root Cause**: Composability Trust + Spot Value ```solidity // VULNERABLE: totalAssets includes donations function totalAssets() public view returns (uint256) { return token.balanceOf(address(this)); // @audit Donatable! } function pricePerShare() public view returns (uint256) { return totalAssets() * 1e18 / totalSupply(); // @audit Inflatable! } ``` **Attack Flow**: 1. Deposit 1 wei → get 1 share (first depositor) 2. Donate 1M tokens directly to vault (not via deposit) 3. pricePerShare = 1M / 1 = 1M per share 4. Victim deposits 999K → gets 0 shares (rounds down) 5. Attacker redeems 1 share → gets everything **Search Queries**: ``` Grep("balanceOf\\(address\\(this\\)\\)", glob="**/*.sol") Grep("totalAssets|totalSupply", glob="**/*.sol") Grep("pricePerShare|exchangeRate", glob="**/*.sol") ``` ### Pattern 5: Missing Slippage Protection **Root Cause**: No minimum output enforcement ```solidity // VULNERABLE: amountOutMin = 0 router.swapExactTokensForTokens( amountIn, 0, // @audit Sandwich target! path, msg.sender, block.timestamp ); ``` **Attack Flow** (Sandwich): 1. See victim's pending swap in mempool 2. Front-run: buy token, raise price 3. Victim's swap executes at worse price 4. Back-run: sell token at higher price 5. Profit from victim's slippage **Search Queries**: ``` Grep("amountOutMin|minAmountOut|minOut", glob="**/*.sol") Grep("swapExact|swap\\(", glob="**/*.sol") ``` ### Pattern 6: Flash Loan Governance **Root Cause**: Snapshot at call time ```solidity // VULNERABLE: Current balance for voting power function propose(bytes calldata action) external { uint256 votes = token.balanceOf(msg.sender); // @audit Current! require(votes >= proposalThreshold); // Attacker: flash loan tokens → propose → return } function vote(uint256 proposalId, bool support) external { uint256 votes = token.balanceOf(msg.sender); // @audit Current! proposals[proposalId].votes += votes; // Attacker: flash loan → vote → return } ``` **Search Queries**: ``` Grep("balanceOf.*vote|vote.*balanceOf", glob="**/*.sol") Grep("propose|quorum|threshold", glob="**/*.sol") ``` --- ## Flash Loan Exploitability Checklist For each value used in critical decisions: - [ ] Can this value be changed within one transaction? - [ ] Does flash loan provide enough capital to move it significantly? - [ ] Is the value read and used in the same transaction? - [ ] Is there a time delay between read and use? - [ ] Are there circuit breakers for extreme values? --- ## Price Source Risk Matrix | Source Type | Manipulation Risk | Attack Vector | |-------------|-------------------|---------------| | DEX Spot (getReserves) | **CRITICAL** | Flash loan swap | | Uniswap V3 slot0 | **CRITICAL** | Flash loan swap | | TWAP < 10 min | **HIGH** | Multi-block or validator | | TWAP 10-30 min | **MEDIUM** | Validator collusion | | TWAP > 30 min | **LOW** | Expensive sustained attack | | Chainlink (no staleness) | **HIGH** | Wait for stale price | | Chainlink (with staleness) | **LOW** | Limited window | | balanceOf(this) | **HIGH** | Direct donation | --- ## Search Query Reference ``` # Find price sources Grep("getReserves|slot0|observe|latestRoundData", glob="**/*.sol") Grep("getPrice|price\\(\\)|oracle", glob="**/*.sol") # Find manipulable values Grep("balanceOf\\(address\\(this\\)\\)", glob="**/*.sol") Grep("totalAssets|totalSupply|pricePerShare", glob="**/*.sol") # Find flash loan interactions Grep("flashLoan|flash\\(|executeOperation", glob="**/*.sol") Grep("onFlashLoan|IERC3156", glob="**/*.sol") # Find vulnerable swaps
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기