我们在上一期文章中,主要介绍了针对领先DeFi借贷协议EulerFinance的闪电贷攻击。在本期文章中,我们会更进一步,深入到闪电贷的源代码,理解什么是闪电贷和闪电贷攻击。
01TL;DR
正如我们上一期文章(「暴雷」启示录:EulerFinance被攻击前因后果复现),闪电贷有如下关键词:
1.不需要抵押资金的贷款
2.放贷、使用资金和还贷「同时」进行
因此利用无需抵押的大额资金,黑客可以:
1.操纵价格,砸盘或拉盘
2.成倍地放大已有漏洞
02什么是闪电贷
闪电贷(Flashloan)是一种去中心化金融(DeFi)的创新产品,它允许用户在不提供任何抵押的情况下,借用协议池中的任意数量的资产,只要在同一笔交易(一个区块)中归还本金和利息。闪电贷的优势在于,它可以让用户利用市场上的套利机会,实现低成本、高收益的操作。闪电贷的风险在于,如果用户无法在规定时间内还款,那么交易会被撤销,用户将损失交易费用和利息。
1常见的闪电贷平台
提到闪电贷,你可能会立刻联想到Aave,这家公司是闪电贷的发明者和领导者。由于闪电贷的资金本身有低风险的特性,较高的需求立刻涌现了一大批闪电贷平台。提供闪电贷服务的头部平台还有:
Uniswap:一个去中心化的交易平台,提供闪电贷服务。用户可以通过Uniswap借用任何支持的代币,并在同一笔交易中进行兑换、做市、套利等操作。
Compound:一个开源的借贷协议,支持多种数字资产的借贷和借款,提供闪电贷服务。用户可以通过Compound借用任何可用的资产,并在同一笔交易中进行还款、抵押、借款等操作。
MakerDAO:一个去中心化的稳定币平台,支持DAI稳定币的发行和交易,提供闪电贷服务。用户可以通过MakerDAO借用DAI,并在同一笔交易中进行还款、兑换、偿还清算罚金等操作。
dYdX:一个去中心化交易所,提供闪电贷服务和开放式借贷市场。用户可以通过dYdX借用任何可用的资产,并在同一笔交易中进行还款、交易、杠杆等操作。
除此之外,常见的还有Nuo、Fulcrum、bZx、DeFiMoneyMarket、ETHLend等。
这些闪电贷平台在功能上都提供了无抵押、即时借贷的服务,细节上的差异更多的是体现在平台的安全性、用户体验和手续费上。
2Uniswap闪电贷
Uniswap是DeFi中最受欢迎的去中心化交易所之一。一般用户接触到Uniswap的途径是网页界面。比如下图展示了ETH-DAI的兑换。我们称两个代币之间的兑换为一个交易对。

但除了使用网站进行交互,我们还可以直接调用智能合约交互。当你想在他们的平台上购买token时:
- 首先需要发送token用于支付
- 然后调用一个swap()的函数,它将发送你刚刚购买的token。
UniswapV2版有一个新的功能,叫做Flashswap,是Uniswap对闪电贷的称呼。这一功能是集成在常规的swap()函数中的。
一个常见的闪电贷操作逻辑有四步,必须在同一个区块中完成:
- 1.发送交易请求,并上传智能合约
- 2.向协议发送代币
- 3.上传的智能合约使用代币交互
- 4.归还代币给协议

因为Uniswap的swap()函数模式是先转账再进行校验,所以第二步可以先将需要的代币借出后,第三步调用自己合约中的uniswapV2Call()函数进行其它操作,完成后第四步再将借的代币归还,完成闪电贷服务。
在代码中,红框部分就是用户预先部署的合约。要想在同一个区块中完成上面的所有操作,用户要将如何使用借出的资金用合约预先定义好,毕竟手工操作的速度没有代码执行快。

而在红框上方的两行中,我们看到有两个转账函数。如注释所言,这是「乐观的转账」──即不校验是否支付就先转账。在最后的部分中,调用完用户合约之后,swap()函数才会慢悠悠地require支付金额。
而无论是否使用闪电贷服务,Uniswap都会对每笔交易收取高达0.3%的手续费。
3AAVE闪电贷
总体而言,AAVE的LendingPool合约中的Flashloan函数提供了类似的闪电贷功能。通过调用Flashloan函数,传入借贷的金额和代币类型借贷地址等参数。执行过程中将代币转给传入的接收地址后会调用传入地址的executeOperation函数,这时可以在executeOperation函数完成其它操作。

AAVE和Uniswap有一点点不同之处在于还款的流程。AAVE闪电贷的还款,是需要借贷者向LendingPool合约授权,在完成闪电贷过程后,由AAVE合约将借用的钱和手续费从借款地址中转回。而在Uniswap中,是由用户调用safeTransfer进行手动转账。

这样可以保证更高的成功率,但相应的可能有一定的合约漏洞风险。
03闪电贷攻击
关于闪电贷攻击的讨论是不断的。有人说闪电贷攻击严格来讲名不副实,因为并没有利用闪电贷的漏洞,而是利用大额的资金提前发现了已有的漏洞。比如利用闪电贷低成本的大额资金,可以:
1.利用闪电贷大的资金量操纵价格,一些项目中价格获取逻辑存在问题。
2.一些项目在抵押或其它过程中会产生瞬时奖励,利用闪电贷获得大额奖励。
3.项目中存在其它的逻辑漏洞,利用闪电贷大的资金量放大套利空间。
我们先从案例进行分析,然后再讨论哪些漏洞容易被闪电贷攻击。
1DFX攻击事件
简单来讲,针对DFX的攻击分为三步:
1.从UniswapV3完成对USDC和XIDR的闪电贷。

2.从DFX的合约中调用flash函数借贷到UCDC和XIDR后又去调用了deposit函数进行了抵押,抵押时可以看到又将黑客借出的钱抵押回了DFX合约。

3.因为用户抵押时将代币又转回到了DFX的合约导致借款前后的余额验证通过,不用再归还借出的闪电贷,但是黑客有抵押操作,此时便可以调用提取函数,提取抵押后离场。

2常见漏洞分析
让我们来盘点一下下面代码都有哪些漏洞。
1.通过代币数量获取价格:

这段代码直接读取了去中心化交易所pair合约中的代币数量,将两者之商作为代币的价格。对于缺乏代码审计经验的人来说,这样写乍一看似乎没有什么问题。但是如果考虑到Uniswap支持闪电贷这一事实,事情就变得有趣了起来。
如果没有闪电贷,两种代币的数量一定是一个减少另一个就增加。但是有了闪电贷,很有可能发生的局面是一个代币减少,而另一种代币没有增加。如果闪电贷的数额不大,两种情况下的差额不大。但如果借出了巨额闪电贷,这个价差将会被立刻拉大,形成巨大套利空间。
这样的漏洞对于没有代码审计经验的人来说很难发现,需要在安全领域有较长时间的深耕和积累,才能形成一套成熟的代码审计体系。
2.发放奖励:

在这段代码中,合约会根据抵押量的大小,立刻将奖励返还给用户地址。这里的问题我们已经提到过了,也是比较好想到。如果奖励发放没有延迟,闪电贷的钱在合约中质押了仅仅一瞬间就能获得奖励,这样无疑是一个巨大的套利漏洞。
3防范措施
在DeFi还没有成熟的时间段内,闪电贷攻击仍将持续不断,成为悬在人们头上的一把达摩克利斯之剑。不同的闪电贷攻击影响的范围也不同,有的可能导致某个看起来毫不相干的DeFi协议暴雷,有的可能波及众多用户。我们能做好的就是做好防范措施,静待DeFi不断成熟:
1.质押挖矿功能和借贷合约做分离,不要将用户抵押的代币转移到借贷合约或者记录变量做运算。
2.借贷时添加特殊重入锁,借贷时不允许抵押。
3.项目在价格获取时采用多数据源的形式,数据对比后减小价格误差。
4.移除流动性时应当先销毁LP,再进行其它调用。
5.奖励的产生尽量采用隔区块或者时间差的形式,可以有效避免闪电贷攻击。
6.项目逻辑问题是导致黑客利用闪电贷放大套利最常见得情况。因此,项目在上线前要做好安全审计和测试,保证项目安全性。
(声明:请读者严格遵守所在地法律法规,本文不代表任何投资建议)