defi-attack-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SKILL: 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.
ProviderMax AmountFee
Aave V3Pool liquidity per asset0.05% (can be 0 for approved borrowers)
dYdXPool liquidity0 (uses internal balance manipulation)
Uniswap V3Pool liquidity per pair0.3% (swap fee tier)
BalancerPool liquidityProtocol-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 cost
Key insight: protocols using AMM spot reserves (
getReserves()
) as price oracles are vulnerable. Must use TWAP or external oracle (Chainlink).
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现货储备(
getReserves()
)作为价格预言机的协议存在漏洞,必须使用TWAP或外部预言机(Chainlink)。

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 tokens
Defense: 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 TypeManipulation CostTime Window
Spot price (
getReserves()
)
Single large swap (flash loanable)Same transaction
TWAP (Time-Weighted Average)Sustained multi-block manipulationMultiple blocks (expensive)
Chainlink aggregatorCompromise ≥ majority of oracle nodesPractically infeasible
预言机类型操纵成本时间窗口
现货价格(
getReserves()
单次大额兑换(可通过闪电贷实现)同一交易内
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 - fees
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 - fees

2.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 >= roundId
If 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 × 2
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 × 2

3.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 profit
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 profit

3.4 MEV Protection Mechanisms

3.4 MEV防护机制

MechanismHow It Works
Flashbots ProtectSends tx to private mempool; only block builder sees it
MEV BlockerRPC endpoint that routes through MEV-aware relayers
Cow Protocol (batch auction)Batch matching eliminates ordering advantage
Encrypted mempoolsThreshold encryption; decrypt only at block build time
MEV-ShareUser captures portion of MEV extracted from their tx

机制工作原理
Flashbots Protect将交易发送到私有内存池,仅区块构建者可见
MEV BlockerRPC端点,通过感知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 / totalAssets
If
totalAssets
is very large relative to
depositAmount * totalShares
, result rounds to 0 → depositor gets no shares but pool keeps the deposit.
Solidity没有浮点数,整数除法会截断小数部分:
shares = depositAmount * totalShares / totalAssets
如果
totalAssets
相对于
depositAmount * totalShares
过大,计算结果会四舍五入为0→存款人得不到任何份额,但池子会保留其存款。

4.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 all
Defenses:
  • 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 时间锁绕过

VectorMethod
Timelock set to 0Admin can execute proposals instantly
emergencyExecute
function
Bypasses timelock for "emergencies"
Guardian/multisig overrideSingle point of failure
Proposal cancellation by attackerFront-run with cancel if threshold met
攻击向量方法
时间锁设置为0管理员可立即执行提案
emergencyExecute
函数
为「紧急情况」绕过时间锁
守护者/多签覆写单点故障
攻击者取消提案满足阈值时抢先运行取消交易

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 tokens

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 tokens

6. BRIDGE EXPLOITS

6. 跨链桥漏洞

6.1 Common Bridge Attack Vectors

6.1 常见跨链桥攻击向量

VectorExample
Signature verification bypassRonin Bridge ($624M) — compromised 5/9 validators
Message replayReplay deposit proof on multiple chains
Fake deposit proofSubmit proof for non-existent L1 deposit
Validator collusionCompromised majority of bridge validators
Smart contract bugWormhole ($320M) — uninitialized guardian set
Upgradeable proxy exploitAttacker 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 signatures

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 signatures

7. 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 50
Defense:
approve(0)
first, then
approve(newAmount)
. Or use
increaseAllowance/decreaseAllowance
.
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 50
防御方案:先执行
approve(0)
,再执行
approve(newAmount)
,或使用
increaseAllowance/decreaseAllowance

7.2 ERC-777 Reentrancy via Hooks

7.2 ERC-777通过钩子实现重入

ERC-777 tokens call
tokensReceived()
hook on the recipient before completing the transfer → classic reentrancy vector.
transfer(attacker, amount)
├── _beforeTokenTransfer hook
├── Balance update
├── tokensReceived() callback to recipient  ← reentrancy window
│   └── attacker re-enters: transfer, swap, deposit, etc.
└── _afterTokenTransfer hook
ERC-777代币在完成转账前会调用接收方的
tokensReceived()
钩子→典型重入向量。
transfer(attacker, amount)
├── _beforeTokenTransfer hook
├── Balance update
├── tokensReceived() callback to recipient  ← reentrancy window
│   └── attacker re-enters: transfer, swap, deposit, etc.
└── _afterTokenTransfer hook

7.3 Fee-on-Transfer Tokens

7.3 转账扣费代币

Tokens that deduct a fee on each transfer. Protocol receives less than
amount
:
solidity
// 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;
每次转账会扣除手续费的代币,协议实际收到的金额小于
amount
solidity
// 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漏洞参考

ExploitDateLossPrimary Vector
Ronin BridgeMar 2022$624MCompromised validator keys
WormholeFeb 2022$320MSignature verification bug
BeanstalkApr 2022$182MFlash loan governance
Mango MarketsOct 2022$114MOracle manipulation
Euler FinanceMar 2023$197MDonation attack + liquidation logic
Curve (reentrancy)Jul 2023$73MVyper compiler reentrancy bug

漏洞事件日期损失主要攻击向量
Ronin Bridge2022年3月6.24亿美元验证者密钥被攻陷
Wormhole2022年2月3.2亿美元签名验证漏洞
Beanstalk2022年4月1.82亿美元闪电贷治理攻击
Mango Markets2022年10月1.14亿美元预言机操纵
Euler Finance2023年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 bugs
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 bugs