http://www.yzthzm.com

深度研究丨有效市场下的闪电攻击

FlashLoan(闪电贷)跟当初的 MakerDAO 一样诞生很早,发力较晚,而一旦发力所带来的一连串连锁创新将引领整个 DeFi 行业迈向新的发展台阶。短短的一两年内,链上金融体系已经初步具备了现代金融框架,不仅可以自成闭环,同时在不断试探外部金融世界,正是这种永葆活力的崭新远景赋予了区块链世界永无止境的探索动力,不再停留在自我怀疑的困境中,如同当年的互联网一样,一切都在发展规律的冥冥护佑下不断蝶变。

(一)FlashLoan 原理

简单来讲,FlashLoan 可以让用户在一笔交易里原子性的完成从借款、一系列的资金利用、还款等操作,做到零成本贷款,仅从目前我们的认知来看,主要用途用于交易套利(如 DEX 和保证金交易平台),但随着 DeFi 的不断复杂和完善,不排除其他潜在用途出现。FlashLoan 是一种新的开放式借贷协议,任何借贷平台都可以选择支持 FlashLoan,从而给自己带来更多的想象空间和流动性。协议首先需要实现 FlashLender,由 FlashLender 帮助用户在一笔交易里完成如下操作:

1.Borrow from any Lending platform
2.executeArbitrage callback
3.Profit
4.Repay the entire amount borrowed, otherwise to Step 
5.the entire transaction revert, nothing happened

大致需要类似如下几个功能合约:

(a)FlashLender

帮助 Arbitrage 合约完成借款操作并调用其 callback

(b)Arbitrage

响应用户请求,调用 FlashLender 合约进行借贷操作,获取资金后调用 TradeExecutor 合约执行特别定义的资金操作

(c)TradeExecutor

往往需要配合一些 wrapper 合约对特定 DeFi 平台进行 API 调用并完成资金操作

(d)ExchangeWrapper (such as KyberWrapper, 0xWrapper, etc al)

这是一类针对 DEX 的 wrapper 合约,利用 DEX 的开发 API 操作,包含将 ETH 等在 DEX 上兑换成其他币种的逻辑,一般包含 getExchangeCost、getMaxMakerAmount、transferTakerFee、parseOrder、parseSignature 等类似方法。例如定义 0x 上的买单:

0xWrapperContract.methods.getTokens(orderAddresses, orderValues);

并由 TradeExecutor 合约 trade() 方法对其进行使用。

深度研究丨有效市场下的闪电攻击

所以从以上看来完成一个 FlashLoan 协议的开发和支持是很简单的事情。然而正是这种简单让平台方对本应该配套的风险控制疏忽大意。在 MOV 的设计准则里一直有这么一句话:每多加一项单独的服务需要配套双倍的风控措施,而每叠加一项组合式的服务却需要配套十倍的风险管理。

(二)闪电攻击

目前 FlashLoan 引起了两起确确实实的金融套利攻击(我们并不认为这是黑客攻击),都是利用了 DEX 交易市场进行最终套利,而且表现出聚集性,前后周期非常短,(这群)攻击者显然已经非常熟悉整个 DeFi 市场数据和运作机制,而且展现了对 FlashLoan 的灵活运用,我们有理由相信,在接下来的几个月里还将会发生更加惊心动魄的攻击。先来看第一起攻击:

第一步(囤粮):利用 FlashLoan 从 dydx 借出 10000 ETH
第二步(囤兵):用其中 5500 ETH 从 Compound 借出 112 BTC
第三步(诈降):去 bZx(“不自信”)做保证金交易,用 1300 ETH 开 5 倍杠杆,将借出来的 ETH 换来约 51 BTC,由于 bZx 使用的是 Kyber Network,而 Kyber Network 最终还是用了 Uniswap,这个过程大幅度拉高了 UniSwap 中 BTC/ETH 的价格,此时套利机会出现
第四步(总攻):将 112 BTC 在 Uniswap 中卖掉,换取更多的 ETH,产生利润
第五步(止战):归还 dydx 借款

逻辑很清晰了,问题根本在于 bZx 的保证金交易大幅度拉升 BTC/ETH 价格导致套利机会出现,而最最根本的问题却是 bZx 竟然没有爆仓:当 Uniswap 中 BTC/ETH 的兑换价从 39 被操纵拉高到 108 时,bZx 上的抵押品应该是不足的,会被爆仓,但 bZx 智能合约却没有要求增加保证金,也没有进行清算。因此本质上是将 bZx 资金池里(大家的)ETH 通过 Uniswap 转移到了从 Compound 借出的 BTC 身上,bZx 储户承担最后的亏损。同时 Uniswap 来回走了两遍,即第一遍用 bZx 杠杆借出的 5637 ETH 换了 51 BTC,第二遍反向,用 Compound 借出的 112 BTC 换了 6871 ETH,所以最后会导致 Uniswap 上 BTC/ETH 均价在 (6871-5637)/(112-51)=20,是低于正常价格 39,因此在第二遍砸盘中,会有一部分 BTC 属于亏损出货,大概 60 BTC 差不多属于对折出售,而亏损的钱被 Uniswap 的做市商赚走了。所以这次攻击,是攻击者充分利用 Uniswap 滑点保护缺陷和 bZx 保证金杠杆交易合约缺陷完成的。

注:关于 bZx 合约缺陷。在其合约代码中有一个 require 调用来检查该头寸是否健康(healthy position),然而由于低级的代码错误(或者风控意识欠缺),仅在 loadDataBytes.length == 0 && sentAmounts [6] == sentAmounts [1] 的情况下,就可以绕过完整性检查(sanity check),最终跳过清算 bZxOracle :: shoudLiquidate。

在第一次攻击后,项目方紧急修补了自身合约缺陷,但紧接着的第二次攻击,则充分利用了 bZx 严重依赖链上预言机获取定价的风险缺陷:

第一步(打入敌人内部):从 bZx 本身通过 FlashLoan 借出 7500 ETH

第二步(牺牲小我):用 540 ETH 在 Kyber 上购买了 92419.7 sUSD,导致 WETH/sUSD 价格瞬间拉低,做多了 sUSD,Kyber 使用了 Uniswap,因此影响到了 Uniswap 上的兑换率,攻击者很聪明,转而用18次小额(20 ETH)继续砸盘拉高 sUSD,最终导致 Uniswap 中 sUSD/WETH 为 1:157,大大偏离正常价格

第三步(援军包围):从 Synthetix 借走所有的 sUSD,然后砸向 bZx,由于 bZx 严重依赖 Uniswap 报价 sUSD,导致攻击者的 sUSD 在 bZx 上价值远高于正常价值,兑换出了大量的 ETH,完成套利

第四步(把叛徒还回):向 bZx 归还 7500 ETH

这是一次非常经典的预言机攻击,全程干净利落。我们认为攻击者对 sUSD 的市场行为和套利空间了若指掌,所以一针见血的选择了 sUSD 和 Synthetix 作为援军,而援军表现的也是十分给力,不仅给出了全部家底,而且成功让 bZx 死心塌地相信 Uniswap 的报价,也没有给 sUSD 在其平台的兑换过多的风控限制。

第二次攻击的影响和意义要超越第一次,这给目前所有 DeFi 产品在预言机喂价机制上开始做出改变和风控管理,才能获取真正的公平市场价值(FMV,fair market value)。预言机大致分为五种:

(1)链下中心化预言机:从单一链下金融系统获取 FMV
(2)链下去中心化预言机:从多个链下金融系统获取 FMV,而且由多方分别掌握,并通过数学公式整合多个价格
(3)链上中心化预言机:往往是单一的 DEX
(4)链上去中心化预言机:由生态治理者参与喂价共治
(5)常量预言机:一般用于稳定币喂价,比如美元稳定币只接受现实世界美元价格

下面是几个主要 DeFi 之前的预言机选择:

深度研究丨有效市场下的闪电攻击

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。