0x1 事件背景
MonoX是一种新的DeFi协议,使用单一代币设计用于流动性池(而不是使用池对)。是通过将存入的代币与 vCASH稳定币组合成一个虚拟对来实现。
零时科技区块链安全情报平台监控到消息,北京时间2021年11月30日,MonoX官方发推文称MonoX智能合约被攻击,导致MONO代币购买池中的MONO代币外,其他所有资产被盗,零时科技安全团队及时对该安全事件进行复盘分析。
0x2 攻击者信息
零时科技安全团队通过初步追踪分析,此次攻击分为Ethereum链和Polygon链,本篇主要分析Ethereum链信息,主要攻击信息如下
- 攻击者钱包地址
https://etherscan.io/address/0xecbe385f78041895c311070f344b55bfaa953258
- 攻击者合约地址
https://etherscan.io/address/0xf079d7911c13369e7fd85607970036d2883afcfd#code
- 攻击交易
https://etherscan.io/tx/0x9f14d093a2349de08f02fc0fb018dadb449351d0cdb7d0738ff69cc6fef5f299
- Monoswap合约
https://etherscan.io/address/0xa1fba7f2079131acb3e2073563ec53c8d43bc144#code
0x3 攻击分析
以下将拆解攻击者交易,方便读者更清晰的了解攻击过程。
第一步:攻击者通过Monoswap将0.1枚WETH兑换为79枚MONO,为后续攻击做准备。
第二步:攻击者通过Monoswap分别移除三笔vCASH流动性。
第三步:攻击者通过Monoswap添加MONO流动性,并进行多达55次的少量MONO代币兑换操作,从而影响池子中的MONO代币价格。
第四步:攻击者初步攻击完成,并分别使用0.07枚MONO代币兑换出4029枚USDT,使用0.08枚MONO代币兑换出4525枚USDT,并将获取的USDT通过Uniswap V2分别兑换为847枚和949枚WETH(共1796枚WETH)。
第五步:由于池中MONO代币价格已经非常高,此步骤中攻击者多次利用极少量MONO代币兑换了453枚WETH,21枚WBTC,515万枚DUCK,4125枚MIM,275枚IMX,并转至攻击者钱包地址。
至此
攻击者通过该笔交易共获取2249枚WETH,21枚WBTC,515万枚DUCK,4125枚MIM,275枚IMX,加上Polygon链攻击获取的资金,攻击者共计获利约3100万美元。看似并不复杂的攻击步骤,为何可以多次取出大量代币,第三步中的多次少量代币的兑换操作为何会对MONO代币价格影响如此之大,我们继续跟进Monoswap合约兑换合约。
0x4 漏洞细节
通过查询交易详情可以找出本次攻击中使用的合约方法主要有两个:
Monoswap.swapExactTokenForToke方法,攻击者进行多次少量代币兑换的方法,用来操控MONO价格。
Monoswap.swapTokenForExactToken方法,攻击者兑换出指定代币的方法,用来获利。
首先来看由于多次的兑换导致代币价格出现极端波动的Monoswap.swapExactTokenForToke方法,由交易方法详细可以看到,攻击者多次兑换时,调用的swapExactTokenForToke方法传入的address tokenIn,address tokenOut,均为MONO Token地址0x2920f7d6134f4669343e70122cA9b8f19Ef8fa5D,继续查看传入的两个相同地址和正常交易的差别,swapExactTokenForToke方法如下:
swapExactTokenForToke调用swapIn方法获取amountOut数量,跟进swapIn方法,主要逻辑如下:
上图swapIn方法中,tokenInPrice,tokenOutPrice价格通过getamountOut方法获取,继续跟进
getamountOut方法中,价格通过_getNewPrice方法获得,继续跟进
getNewPrice方法方法中,通过TxType判断后会进行不同的价格公式获取,当该条件执行else时,将调用getNewPrice方法传入的参数带入,可得到price公式中,分母减小,price价格增大的逻辑,虽然这里并不知道TxType.SELL和TxType.BUY的值,但由于传入的两个Token地址均为MONO,所以当任意一个值满足条件时,均会达成price价格增大的效果,并且在swapIn方法中,由于两个Token地址均为MONO,所以_updateTokenInfo方法会继续执行。
攻击者通过多次兑换,将MONO价格推至顶峰,随后调用第二个攻击的核心方法swapTokenForExactToken获取大量代币。
目前,MonoX官方正在寻求与黑客通话,暂未声明合约修改方案和补偿方案。
0x5 总结
通过此次攻击事件来看,攻击者主要利用Monoswap合约未进行兑换地址是否相同的检查,多次进行少量代币兑换,无限抬高MONO代币价格,最终将通过价格控制,转走池子中所有的Token代币,DeFi项目中类似的攻击事件居多,为何还会频频发生,对于DeFi项目而言,合约代码的安全,代币价格的相对稳定,旧版本的及时更新都是保证项目安全极其重要的部分,任何细节的马虎都可能导致项目及用户资金受到损失。对于此类闪电贷攻击事件,零时科技安全团队给出以下建议。
0x6 安全建议
- 对于合约代码安全,可找多家安全审计公司进行审计。
- 使用可信的并且安全可靠的预言机,如Chainlink获取价格
- 对敏感性较强的代码,要做到及时更新完善。