defi-attack-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSKILL: DeFi Attack Patterns — Expert Attack Playbook
SKILL:DeFi 攻击模式——专业攻击手册
AI LOAD INSTRUCTION: Expert DeFi exploitation techniques. Covers flash loan mechanics, oracle manipulation (spot vs TWAP), MEV extraction (sandwich, JIT, liquidation), precision loss attacks, governance exploits, bridge vulnerabilities, and token standard pitfalls. Base models often miss the single-transaction atomicity constraint of flash loans and the distinction between spot price and TWAP manipulation.
AI加载说明:专业DeFi利用技术,涵盖闪电贷机制、预言机操纵(现货价格vs TWAP)、MEV提取(三明治攻击、JIT、清算)、精度丢失攻击、治理漏洞、跨链桥漏洞以及代币标准陷阱。基础模型通常会忽略闪电贷的单交易原子性约束,以及现货价格操纵和TWAP操纵之间的区别。
0. RELATED ROUTING
0. 相关关联指引
- smart-contract-vulnerabilities for underlying Solidity vulnerability patterns (reentrancy, integer overflow, delegatecall)
- deserialization-insecure when targeting off-chain bridge relayer or indexer infrastructure
- smart-contract-vulnerabilities 查看底层Solidity漏洞模式(重入、整数溢出、delegatecall)
- deserialization-insecure 适用于针对链下跨链桥中继器或索引器基础设施的攻击场景
1. FLASH LOAN ATTACKS
1. 闪电贷攻击
1.1 Mechanism
1.1 机制
Flash loans provide uncollateralized borrowing within a single transaction. The entire borrow → use → repay cycle must complete atomically; if repayment fails, the transaction reverts as if nothing happened.
| Provider | Max Amount | Fee |
|---|---|---|
| Aave V3 | Pool liquidity per asset | 0.05% (can be 0 for approved borrowers) |
| dYdX | Pool liquidity | 0 (uses internal balance manipulation) |
| Uniswap V3 | Pool liquidity per pair | 0.3% (swap fee tier) |
| Balancer | Pool liquidity | Protocol-configurable |
闪电贷可在单交易内提供无抵押借贷,整个「借贷→使用→还款」周期必须原子性完成;如果还款失败,交易将回滚,就像什么都没发生过一样。
| 提供商 | 最大额度 | 手续费 |
|---|---|---|
| Aave V3 | 各资产的池子流动性 | 0.05%(获批借款人可享0手续费) |
| dYdX | 池子流动性 | 0(使用内部余额操纵实现) |
| Uniswap V3 | 各交易对的池子流动性 | 0.3%(兑换手续费层级) |
| Balancer | 池子流动性 | 协议可配置 |
1.2 Price Oracle Manipulation
1.2 价格预言机操纵
1. Flash borrow 100,000 WETH
2. Swap 100,000 WETH → TOKEN on AMM_A
→ TOKEN spot price on AMM_A skyrockets
3. On Lending_Protocol (reads AMM_A spot price as oracle):
→ Deposit small TOKEN collateral (valued at inflated price)
→ Borrow large amount of WETH against it
4. Swap TOKEN back → WETH on AMM_A (restore price)
5. Repay flash loan (100,000 WETH + fee)
6. Keep borrowed WETH from Lending_Protocol minus collateral costKey insight: protocols using AMM spot reserves () as price oracles are vulnerable. Must use TWAP or external oracle (Chainlink).
getReserves()1. Flash borrow 100,000 WETH
2. Swap 100,000 WETH → TOKEN on AMM_A
→ TOKEN spot price on AMM_A skyrockets
3. On Lending_Protocol (reads AMM_A spot price as oracle):
→ Deposit small TOKEN collateral (valued at inflated price)
→ Borrow large amount of WETH against it
4. Swap TOKEN back → WETH on AMM_A (restore price)
5. Repay flash loan (100,000 WETH + fee)
6. Keep borrowed WETH from Lending_Protocol minus collateral cost核心要点:使用AMM现货储备()作为价格预言机的协议存在漏洞,必须使用TWAP或外部预言机(Chainlink)。
getReserves()1.3 Liquidity Pool Drain via Reentrancy
1.3 重入导致流动性池被盗
Flash borrow → deposit into pool → trigger reentrancy during callback → withdraw more than deposited → repay loan.
Exploits the combination of flash loan capital with reentrancy in pool accounting logic.
闪电贷借款→存入池子→回调期间触发重入→提取超出存入额的资产→偿还贷款。
利用了闪电贷资金与池子记账逻辑中重入漏洞的组合。
1.4 Governance Flash Borrow
1.4 闪电贷治理攻击
1. Flash borrow governance tokens
2. Create/vote on malicious proposal (if no snapshot or timelock)
3. Proposal passes instantly
4. Execute proposal (drain treasury, change admin, etc.)
5. Return governance tokensDefense: snapshot-based voting (Compound Governor Bravo), timelocks, minimum proposal period.
1. Flash borrow governance tokens
2. Create/vote on malicious proposal (if no snapshot or timelock)
3. Proposal passes instantly
4. Execute proposal (drain treasury, change admin, etc.)
5. Return governance tokens防御方案:基于快照的投票(Compound Governor Bravo)、时间锁、最低提案等待期。
2. PRICE ORACLE MANIPULATION
2. 价格预言机操纵
2.1 Spot Price vs TWAP
2.1 现货价格 vs TWAP
| Oracle Type | Manipulation Cost | Time Window |
|---|---|---|
Spot price ( | Single large swap (flash loanable) | Same transaction |
| TWAP (Time-Weighted Average) | Sustained multi-block manipulation | Multiple blocks (expensive) |
| Chainlink aggregator | Compromise ≥ majority of oracle nodes | Practically infeasible |
| 预言机类型 | 操纵成本 | 时间窗口 |
|---|---|---|
现货价格( | 单次大额兑换(可通过闪电贷实现) | 同一交易内 |
| TWAP(时间加权平均价格) | 持续多区块操纵 | 多个区块(成本高昂) |
| Chainlink聚合器 | 攻陷≥多数预言机节点 | 几乎不可实现 |
2.2 AMM Manipulation Flow
2.2 AMM操纵流程
Normal state: Pool has 1000 ETH + 1,000,000 USDC → price = 1000 USDC/ETH
Attack:
├── Swap 9000 ETH into pool
│ Pool now: 10000 ETH + 100,000 USDC (constant product)
│ Spot price: 10 USDC/ETH (crashed 100x)
├── Dependent contract reads this price
│ → Liquidates positions at wrong price
│ → Or allows cheap borrowing against ETH collateral
├── Swap back: buy ETH with USDC
│ Price restores to ~1000 USDC/ETH
└── Net profit = value extracted from dependent contract - swap slippage - feesNormal state: Pool has 1000 ETH + 1,000,000 USDC → price = 1000 USDC/ETH
Attack:
├── Swap 9000 ETH into pool
│ Pool now: 10000 ETH + 100,000 USDC (constant product)
│ Spot price: 10 USDC/ETH (crashed 100x)
├── Dependent contract reads this price
│ → Liquidates positions at wrong price
│ → Or allows cheap borrowing against ETH collateral
├── Swap back: buy ETH with USDC
│ Price restores to ~1000 USDC/ETH
└── Net profit = value extracted from dependent contract - swap slippage - fees2.3 Chainlink Oracle Staleness
2.3 Chainlink预言机陈旧问题
solidity
(, int price, , uint updatedAt, ) = priceFeed.latestRoundData();
// Missing checks:
// 1. price > 0
// 2. updatedAt != 0
// 3. block.timestamp - updatedAt < HEARTBEAT
// 4. answeredInRound >= roundIdIf oracle is stale (network congestion, L2 sequencer down), price can be hours old → arbitrage against stale price.
L2 Sequencer Risk: If Arbitrum/Optimism sequencer is down, Chainlink prices freeze. When it comes back, prices jump → mass liquidations at wrong prices.
solidity
(, int price, , uint updatedAt, ) = priceFeed.latestRoundData();
// Missing checks:
// 1. price > 0
// 2. updatedAt != 0
// 3. block.timestamp - updatedAt < HEARTBEAT
// 4. answeredInRound >= roundId如果预言机数据陈旧(网络拥堵、L2排序器宕机),价格可能是几小时前的→可利用陈旧价格进行套利。
L2排序器风险:如果Arbitrum/Optimism排序器宕机,Chainlink价格会冻结。恢复服务时价格跳涨→会出现大量按错误价格清算的情况。
3. MEV (MAXIMAL EXTRACTABLE VALUE)
3. MEV(最大可提取价值)
3.1 Sandwich Attack
3.1 三明治攻击
Mempool observation: victim submits swap TOKEN_A → TOKEN_B with slippage 1%
Front-run: Buy TOKEN_B (increase price)
Victim tx: Swap executes at worse price (within slippage tolerance)
Back-run: Sell TOKEN_B (profit from price impact)
Profit = victim's price impact - gas costs × 2Mempool observation: victim submits swap TOKEN_A → TOKEN_B with slippage 1%
Front-run: Buy TOKEN_B (increase price)
Victim tx: Swap executes at worse price (within slippage tolerance)
Back-run: Sell TOKEN_B (profit from price impact)
Profit = victim's price impact - gas costs × 23.2 JIT (Just-In-Time) Liquidity
3.2 JIT(即时)流动性攻击
1. Observe large pending swap in mempool
2. Provide concentrated liquidity in the exact price range (Uniswap V3 tick)
3. Victim's swap executes → JIT LP earns majority of fees
4. Remove liquidity immediately after swap
5. Profit = fee earned - gas - impermanent loss (minimal for single block)1. Observe large pending swap in mempool
2. Provide concentrated liquidity in the exact price range (Uniswap V3 tick)
3. Victim's swap executes → JIT LP earns majority of fees
4. Remove liquidity immediately after swap
5. Profit = fee earned - gas - impermanent loss (minimal for single block)3.3 Liquidation MEV
3.3 清算MEV
1. Monitor lending protocols for positions approaching liquidation threshold
2. When price oracle updates → position becomes liquidatable
3. Front-run other liquidators → execute liquidation
4. Receive liquidation bonus (typically 5-15% of collateral)
5. Sell collateral for profit1. Monitor lending protocols for positions approaching liquidation threshold
2. When price oracle updates → position becomes liquidatable
3. Front-run other liquidators → execute liquidation
4. Receive liquidation bonus (typically 5-15% of collateral)
5. Sell collateral for profit3.4 MEV Protection Mechanisms
3.4 MEV防护机制
| Mechanism | How It Works |
|---|---|
| Flashbots Protect | Sends tx to private mempool; only block builder sees it |
| MEV Blocker | RPC endpoint that routes through MEV-aware relayers |
| Cow Protocol (batch auction) | Batch matching eliminates ordering advantage |
| Encrypted mempools | Threshold encryption; decrypt only at block build time |
| MEV-Share | User captures portion of MEV extracted from their tx |
| 机制 | 工作原理 |
|---|---|
| Flashbots Protect | 将交易发送到私有内存池,仅区块构建者可见 |
| MEV Blocker | RPC端点,通过感知MEV的中继器路由交易 |
| Cow Protocol(批量拍卖) | 批量匹配消除排序优势 |
| 加密内存池 | 门限加密,仅在区块构建时解密 |
| MEV-Share | 用户可从自身交易产生的MEV中获得部分收益 |
4. PRECISION LOSS EXPLOITATION
4. 精度丢失利用
4.1 Rounding Errors in Token Calculations
4.1 代币计算中的舍入误差
Solidity has no floating point. Integer division truncates:
shares = depositAmount * totalShares / totalAssetsIf is very large relative to , result rounds to 0 → depositor gets no shares but pool keeps the deposit.
totalAssetsdepositAmount * totalSharesSolidity没有浮点数,整数除法会截断小数部分:
shares = depositAmount * totalShares / totalAssets如果相对于过大,计算结果会四舍五入为0→存款人得不到任何份额,但池子会保留其存款。
totalAssetsdepositAmount * totalShares4.2 First Depositor / Vault Inflation Attack
4.2 首次存款/金库通胀攻击
1. Attacker deposits 1 wei → receives 1 share
2. Attacker donates 1,000,000 tokens directly to vault (not via deposit)
3. Vault state: 1,000,001 tokens, 1 share
4. Victim deposits 999,999 tokens:
shares = 999,999 * 1 / 1,000,001 = 0 (integer truncation)
5. Victim gets 0 shares; attacker owns 100% of vault (now 2,000,000 tokens)
6. Attacker withdraws allDefenses:
- Mint dead shares on first deposit (OpenZeppelin ERC4626 offset)
- Require minimum initial deposit
- Internal accounting with virtual offset
1. Attacker deposits 1 wei → receives 1 share
2. Attacker donates 1,000,000 tokens directly to vault (not via deposit)
3. Vault state: 1,000,001 tokens, 1 share
4. Victim deposits 999,999 tokens:
shares = 999,999 * 1 / 1,000,001 = 0 (integer truncation)
5. Victim gets 0 shares; attacker owns 100% of vault (now 2,000,000 tokens)
6. Attacker withdraws all防御方案:
- 首次存款时铸造死亡份额(OpenZeppelin ERC4626偏移方案)
- 要求最低初始存款
- 带虚拟偏移的内部记账
4.3 Dust Attack via Precision Truncation
4.3 精度截断导致的粉尘攻击
Repeated small operations where each truncation loses 1 wei. Accumulate across thousands of operations → material loss.
重复执行小额操作,每次截断损失1 wei。在数千次操作中累积→产生实质性损失。
5. GOVERNANCE ATTACKS
5. 治理攻击
5.1 Flash Loan Governance
5.1 闪电贷治理攻击
Borrow governance tokens → vote → return. Only works if protocol doesn't snapshot balances before voting.
借入治理代币→投票→归还代币。仅在协议投票前不对余额做快照时生效。
5.2 Timelock Bypass
5.2 时间锁绕过
| Vector | Method |
|---|---|
| Timelock set to 0 | Admin can execute proposals instantly |
| Bypasses timelock for "emergencies" |
| Guardian/multisig override | Single point of failure |
| Proposal cancellation by attacker | Front-run with cancel if threshold met |
| 攻击向量 | 方法 |
|---|---|
| 时间锁设置为0 | 管理员可立即执行提案 |
| 为「紧急情况」绕过时间锁 |
| 守护者/多签覆写 | 单点故障 |
| 攻击者取消提案 | 满足阈值时抢先运行取消交易 |
5.3 Quorum Manipulation
5.3 法定人数操纵
Protocol requires 10% quorum (10M tokens out of 100M supply)
├── Flash borrow 10M governance tokens
├── Create proposal: set admin = attacker
├── Vote with borrowed tokens → meets quorum
├── If no timelock: execute immediately
└── Return tokensProtocol requires 10% quorum (10M tokens out of 100M supply)
├── Flash borrow 10M governance tokens
├── Create proposal: set admin = attacker
├── Vote with borrowed tokens → meets quorum
├── If no timelock: execute immediately
└── Return tokens6. BRIDGE EXPLOITS
6. 跨链桥漏洞
6.1 Common Bridge Attack Vectors
6.1 常见跨链桥攻击向量
| Vector | Example |
|---|---|
| Signature verification bypass | Ronin Bridge ($624M) — compromised 5/9 validators |
| Message replay | Replay deposit proof on multiple chains |
| Fake deposit proof | Submit proof for non-existent L1 deposit |
| Validator collusion | Compromised majority of bridge validators |
| Smart contract bug | Wormhole ($320M) — uninitialized guardian set |
| Upgradeable proxy exploit | Attacker gains upgrade authority → swap implementation |
| 向量 | 示例 |
|---|---|
| 签名验证绕过 | Ronin Bridge(6.24亿美元)→攻陷5/9验证者 |
| 消息重放 | 在多条链上重放存款证明 |
| 伪造存款证明 | 提交不存在的L1存款证明 |
| 验证者合谋 | 攻陷多数跨链桥验证者 |
| 智能合约漏洞 | Wormhole(3.2亿美元)→守护者集未初始化 |
| 可升级代理漏洞 | 攻击者获得升级权限→替换实现合约 |
6.2 Cross-Chain Message Verification
6.2 跨链消息验证
Secure pattern:
├── Source chain: emit event with (destination, amount, nonce, chainId)
├── Relayer: submit proof (Merkle proof of event inclusion)
├── Destination chain: verify proof against known source block header
│ ├── Check nonce not replayed
│ ├── Check chainId matches
│ ├── Verify Merkle proof against trusted root
│ └── Mint/release tokens
Vulnerable pattern:
├── Relayer: submit (destination, amount) signed by N-of-M validators
└── If M is small or keys are compromised → forge signaturesSecure pattern:
├── Source chain: emit event with (destination, amount, nonce, chainId)
├── Relayer: submit proof (Merkle proof of event inclusion)
├── Destination chain: verify proof against known source block header
│ ├── Check nonce not replayed
│ ├── Check chainId matches
│ ├── Verify Merkle proof against trusted root
│ └── Mint/release tokens
Vulnerable pattern:
├── Relayer: submit (destination, amount) signed by N-of-M validators
└── If M is small or keys are compromised → forge signatures7. TOKEN STANDARD EDGE CASES
7. 代币标准边缘案例
7.1 ERC-20 Approval Front-Running
7.1 ERC-20授权抢先交易
1. Alice approves Bob for 100 tokens
2. Alice wants to change approval to 50 tokens
3. Bob sees the approval change tx in mempool
4. Bob front-runs: transferFrom(Alice, Bob, 100) — uses old approval
5. Alice's approval change executes: approval = 50
6. Bob calls transferFrom(Alice, Bob, 50) — uses new approval
7. Bob extracted 150 tokens instead of 50Defense: first, then . Or use .
approve(0)approve(newAmount)increaseAllowance/decreaseAllowance1. Alice approves Bob for 100 tokens
2. Alice wants to change approval to 50 tokens
3. Bob sees the approval change tx in mempool
4. Bob front-runs: transferFrom(Alice, Bob, 100) — uses old approval
5. Alice's approval change executes: approval = 50
6. Bob calls transferFrom(Alice, Bob, 50) — uses new approval
7. Bob extracted 150 tokens instead of 50防御方案:先执行,再执行,或使用。
approve(0)approve(newAmount)increaseAllowance/decreaseAllowance7.2 ERC-777 Reentrancy via Hooks
7.2 ERC-777通过钩子实现重入
ERC-777 tokens call hook on the recipient before completing the transfer → classic reentrancy vector.
tokensReceived()transfer(attacker, amount)
├── _beforeTokenTransfer hook
├── Balance update
├── tokensReceived() callback to recipient ← reentrancy window
│ └── attacker re-enters: transfer, swap, deposit, etc.
└── _afterTokenTransfer hookERC-777代币在完成转账前会调用接收方的钩子→典型重入向量。
tokensReceived()transfer(attacker, amount)
├── _beforeTokenTransfer hook
├── Balance update
├── tokensReceived() callback to recipient ← reentrancy window
│ └── attacker re-enters: transfer, swap, deposit, etc.
└── _afterTokenTransfer hook7.3 Fee-on-Transfer Tokens
7.3 转账扣费代币
Tokens that deduct a fee on each transfer. Protocol receives less than :
amountsolidity
// Vulnerable: assumes received == amount
token.transferFrom(msg.sender, address(this), amount);
deposits[msg.sender] += amount; // overcredits by fee amount
// Fixed: measure actual balance change
uint before = token.balanceOf(address(this));
token.transferFrom(msg.sender, address(this), amount);
uint received = token.balanceOf(address(this)) - before;
deposits[msg.sender] += received;每次转账会扣除手续费的代币,协议实际收到的金额小于:
amountsolidity
// Vulnerable: assumes received == amount
token.transferFrom(msg.sender, address(this), amount);
deposits[msg.sender] += amount; // overcredits by fee amount
// Fixed: measure actual balance change
uint before = token.balanceOf(address(this));
token.transferFrom(msg.sender, address(this), amount);
uint received = token.balanceOf(address(this)) - before;
deposits[msg.sender] += received;7.4 Rebasing Tokens
7.4 Rebasing代币
Tokens that automatically adjust balances (e.g., Aave aTokens, stETH). Protocols holding rebasing tokens may have accounting mismatches if they cache balances.
自动调整余额的代币(例如Aave aTokens、stETH)。持有Rebasing代币的协议如果缓存余额,可能会出现记账不匹配的问题。
8. NOTABLE DEFI EXPLOITS REFERENCE
8. 知名DeFi漏洞参考
| Exploit | Date | Loss | Primary Vector |
|---|---|---|---|
| Ronin Bridge | Mar 2022 | $624M | Compromised validator keys |
| Wormhole | Feb 2022 | $320M | Signature verification bug |
| Beanstalk | Apr 2022 | $182M | Flash loan governance |
| Mango Markets | Oct 2022 | $114M | Oracle manipulation |
| Euler Finance | Mar 2023 | $197M | Donation attack + liquidation logic |
| Curve (reentrancy) | Jul 2023 | $73M | Vyper compiler reentrancy bug |
| 漏洞事件 | 日期 | 损失 | 主要攻击向量 |
|---|---|---|---|
| Ronin Bridge | 2022年3月 | 6.24亿美元 | 验证者密钥被攻陷 |
| Wormhole | 2022年2月 | 3.2亿美元 | 签名验证漏洞 |
| Beanstalk | 2022年4月 | 1.82亿美元 | 闪电贷治理攻击 |
| Mango Markets | 2022年10月 | 1.14亿美元 | 预言机操纵 |
| Euler Finance | 2023年3月 | 1.97亿美元 | 捐赠攻击+清算逻辑漏洞 |
| Curve(重入漏洞) | 2023年7月 | 7300万美元 | Vyper编译器重入漏洞 |
9. DECISION TREE
9. 决策树
Analyzing a DeFi protocol?
├── Does it use price oracles?
│ ├── Spot price (AMM reserves)? → Flash loan manipulation (Section 1.2)
│ │ └── Can oracle be manipulated in single tx? → HIGH RISK
│ ├── TWAP? → Multi-block manipulation needed → MEDIUM RISK
│ ├── Chainlink? → Check staleness handling (Section 2.3)
│ │ ├── Heartbeat check present? → OK
│ │ └── L2? → Check sequencer uptime oracle
│ └── Multiple oracles with fallback? → Evaluate each
├── Does it accept external tokens?
│ ├── Yes → Check fee-on-transfer handling (Section 7.3)
│ ├── ERC-777 tokens accepted? → Reentrancy via hooks (Section 7.2)
│ └── Rebasing tokens? → Accounting mismatch (Section 7.4)
├── Does it have governance?
│ ├── Yes → Flash loan governance possible? (Section 5.1)
│ │ ├── Snapshot-based voting? → Safer
│ │ └── Live balance voting? → Flash borrow attack
│ ├── Timelock present? → Check for bypass (Section 5.2)
│ └── Quorum threshold vs flash-loanable supply? (Section 5.3)
├── Is it a vault / yield aggregator?
│ ├── Yes → First depositor attack (Section 4.2)
│ │ └── Virtual offset or dead shares? → Mitigated
│ └── Precision loss in share calculation? (Section 4.1)
├── Is it a bridge?
│ ├── Yes → Load bridge vectors (Section 6)
│ │ ├── Validator set size and key management?
│ │ ├── Replay protection (nonce + chainId)?
│ │ └── Upgradeable? → Who holds upgrade key?
│ └── No → Continue
├── User-facing swap functionality?
│ ├── Yes → MEV exposure (Section 3)
│ │ ├── Slippage protection enforced?
│ │ └── Private mempool integration?
│ └── No → Continue
└── Load [smart-contract-vulnerabilities](../smart-contract-vulnerabilities/SKILL.md)
for underlying Solidity-level bugsAnalyzing a DeFi protocol?
├── Does it use price oracles?
│ ├── Spot price (AMM reserves)? → Flash loan manipulation (Section 1.2)
│ │ └── Can oracle be manipulated in single tx? → HIGH RISK
│ ├── TWAP? → Multi-block manipulation needed → MEDIUM RISK
│ ├── Chainlink? → Check staleness handling (Section 2.3)
│ │ ├── Heartbeat check present? → OK
│ │ └── L2? → Check sequencer uptime oracle
│ └── Multiple oracles with fallback? → Evaluate each
├── Does it accept external tokens?
│ ├── Yes → Check fee-on-transfer handling (Section 7.3)
│ ├── ERC-777 tokens accepted? → Reentrancy via hooks (Section 7.2)
│ └── Rebasing tokens? → Accounting mismatch (Section 7.4)
├── Does it have governance?
│ ├── Yes → Flash loan governance possible? (Section 5.1)
│ │ ├── Snapshot-based voting? → Safer
│ │ └── Live balance voting? → Flash borrow attack
│ ├── Timelock present? → Check for bypass (Section 5.2)
│ └── Quorum threshold vs flash-loanable supply? (Section 5.3)
├── Is it a vault / yield aggregator?
│ ├── Yes → First depositor attack (Section 4.2)
│ │ └── Virtual offset or dead shares? → Mitigated
│ └── Precision loss in share calculation? (Section 4.1)
├── Is it a bridge?
│ ├── Yes → Load bridge vectors (Section 6)
│ │ ├── Validator set size and key management?
│ │ ├── Replay protection (nonce + chainId)?
│ │ └── Upgradeable? → Who holds upgrade key?
│ └── No → Continue
├── User-facing swap functionality?
│ ├── Yes → MEV exposure (Section 3)
│ │ ├── Slippage protection enforced?
│ │ └── Private mempool integration?
│ └── No → Continue
└── Load [smart-contract-vulnerabilities](../smart-contract-vulnerabilities/SKILL.md)
for underlying Solidity-level bugs