第三章:闪电贷攻击——DeFi世界的双刃剑

说实话,我第一次接触闪电贷这个概念时,第一反应是「这玩意儿也太魔幻了吧?」

零抵押、即时借款、同一笔交易内还清——听起来像天方夜谭。但以太坊的交易原子性让它变成了现实。我曾在审计一个借贷协议时,发现开发者完全没考虑闪电贷的风险,结果可想而知。

3.1 闪电贷原理:为什么能「空手套白狼」?

闪电贷的核心就一句话:在同一笔交易中借出并归还资金

如果借款人在交易结束时没还钱,整个交易就回滚——就像什么都没发生过。这利用了以太坊的原子性特性。

关键机制:

  • 借款 → 操作 → 还款 → 检查余额 → 成功/回滚
  • 所有步骤在同一个区块内完成
  • 无需抵押,因为「不还钱就回滚」

我习惯把闪电贷比作「图书馆借书」:你借走一本书,在图书馆关门(交易结束)前必须放回原处。放不回去?那这本书你压根没借走过。

// 闪电贷核心逻辑(简化版)
function flashLoan(uint256 amount) external {
    uint256 balanceBefore = token.balanceOf(address(this));
    
    // 1. 把币借给用户
    token.transfer(msg.sender, amount);
    
    // 2. 调用用户的回调函数
    IFlashLoanReceiver(msg.sender).execute();
    
    // 3. 检查余额是否足够(本金+手续费)
    require(token.balanceOf(address(this)) >= balanceBefore + fee, "Flash loan failed");
}

3.2 典型攻击案例:那些年我见过的「骚操作」

我在2021年审计过一个项目,代码里有个明显的价格预言机漏洞。当时我就跟团队说:「这玩意儿不出一个月必被闪电贷攻击。」结果两周后就出事了。

案例一:bZx 攻击(2020年2月)

这是闪电贷攻击的「鼻祖」案例。攻击者利用闪电贷借入大量ETH,然后通过一系列操作操纵了合成资产的价格。

攻击流程:

  1. 从dYdX借入10,000 ETH(闪电贷)
  2. 用5,500 ETH在Compound做空
  3. 用剩下的ETH在Uniswap拉高sUSD价格
  4. 用拉高后的sUSD在bZx借出更多ETH
  5. 归还闪电贷,净赚约30万美元

说白了,攻击者就是利用不同协议之间的价格差,加上闪电贷提供的「无限弹药」。

案例二:PancakeBunny 攻击(2021年5月)

这个案例更典型。攻击者通过闪电贷操纵了BUNNY代币的价格,然后利用协议中的「铸币」功能套利。

// 攻击者核心操作(伪代码)
1. flashLoan(大量BNB)
2. swap(BNB → BUNNY)  // 拉高BUNNY价格
3. deposit(BUNNY)      // 存入获得高额奖励
4. withdraw()          // 取出时BUNNY价格已回落
5. repay(flashLoan)    // 净赚差价

嗯,这里要注意:所有依赖链上AMM价格的协议,都是闪电贷攻击的潜在目标

3.3 价格操纵与套利:闪电贷的「正确用法」

其实闪电贷本身是中性的。它既可以被用来攻击,也可以用来做正经套利。

合法套利场景:

  • DEX价差套利:在不同交易所之间搬砖
  • 清算套利:帮别人还债赚清算奖励
  • 抵押品替换:优化借贷仓位

我见过一个团队专门写闪电贷套利机器人,月入百万美元。他们用的就是同一套技术——只是没去碰那些有漏洞的协议。

为什么会有人用闪电贷做套利?因为资金效率高啊。你想想看,传统套利需要准备大量本金,闪电贷让你零成本起步。

3.4 防御策略:如何让你的协议「百毒不侵」

我曾经审计过一个项目,代码写得挺漂亮,但就是没防闪电贷。我跟他们说:「你们这个价格预言机,随便一个闪电贷就能打穿。」

下面是我总结的防御策略,每一条都是血泪教训:

策略 说明 我踩过的坑
使用TWAP预言机 用时间加权平均价格,而非瞬时价格 有个项目用Uniswap即时价格,被闪电贷打爆
引入价格延迟 价格更新后延迟一段时间才生效 延迟太短等于没延迟
限制单笔交易规模 设置最大可操作金额 但太保守会影响用户体验
检查交易来源 禁止合约调用(仅限EOA) 但会误伤闪电贷套利机器人
使用Chainlink等去中心化预言机 聚合多个数据源,抗操纵 成本较高,但值得

我的核心建议:

  • 永远不要信任单笔交易内的价格数据
  • 所有关键价格必须使用外部预言机或TWAP
  • 对闪电贷攻击做专门的单元测试
  • 设置合理的滑点保护

我曾经在一个项目中看到这样的代码:

// ❌ 危险写法:直接使用池子即时价格
uint256 price = uniswap.getReserves() / totalSupply;

// ✅ 安全写法:使用TWAP
uint256 price = uniswap.consult(tokenIn, amountIn, 30 minutes);

就这一行代码的区别,决定了协议是安全还是等着被薅羊毛。

3.5 知识体系总览

下面这张图是我自己画的,把闪电贷攻击的整个知识体系串起来了:

闪电贷攻击知识体系 闪电贷原理 典型攻击案例 价格操纵与套利 防御策略 bZx攻击(2020) PancakeBunny攻击(2021) Harvest Finance攻击 AMM价格操纵 预言机价格操纵 跨协议套利 TWAP预言机 价格延迟机制 Chainlink预言机 核心原则:永远不要信任单笔交易内的价格

这张图把闪电贷攻击的三大块串起来了:攻击案例、价格操纵、防御策略。核心就一句话——别信瞬时价格

避坑指南:

我曾经审计过一个项目,他们用了Uniswap V3的TWAP预言机,但时间窗口设成了1分钟。我告诉他们:「1分钟太短了,闪电贷可以在一个区块内完成攻击。」最后改成了30分钟,安全多了。

好了,闪电贷这块就聊到这儿。记住:闪电贷本身不是问题,问题在于你的协议有没有为它做好准备。

专注资料整理