Vee Finance 攻击策略

Vee Finance 是fork Compound Protocol的借贷协议,并在此基础上添加了杠杆交易逻辑。用户可以通过抵押资产获得贷款凭证,贷款凭证可以在协议中使用。

相关地址 被攻击合约地址(开源):0xd1F855ceF146D36CC5851E2139c54524420797f2

被攻击合约地址实例(开源):0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7

预言机地址(未开源):0x750ef353dd552fb90c215edca60ec0b5dea504cd 未开源不能分析,根据项目方反馈oracle机的价格feed来源仅使用Pangolin交易池的价格,矿池价格波动超过3%,oracle机将刷新价格。

主要原因 事故原因主要是在杠杆交易创建订单过程中,Oracle仅使用Pangolin交易所的价格作为喂价源,矿池价格波动幅度超过3%。 预言机会刷新价格,导致攻击者操纵了Pangolin交易池的价格。 操纵Vee Finance预言机价格和收购预言机价格没有进行小数处理,导致掉期前预期的滑点检查没有起作用。 直接原因 预言机价格源单一,刷新条件受Pangolin交易所代币实时数量影响(矿池价格波动3%,会刷新)。 价格获取尚未针对小数进行处理。

详细分析

1.执行保证金交易时,将调用以下代码块中的 createOrderERC20ToERC20 函数来创建订单。

2.创建订单后,代币交换将通过以下代码块的第 5 行进行。

3.在令牌交换之前,将通过以下代码块第 9 行的 getAmountOutMin 函数检查预期的滑点。

4.检查滑点时,通过下面代码块的第12行和第13行获取oracle的priceA和PriceB报价,然后通过下面的第15行计算当前价格可以兑换TokenB的TokenA数量。最后,与在 Pangolin 池中获得的代币数量进行比较。如果池中可兑换的TokenB数量大于或等于使用oracle可兑换的TokenB的预期数量,则可判断池价格正确且不受控制,且订单创建逻辑继续。

5. 但是,通过链上记录,得到oracle价格的时候,本来是有大约5%的滑点检测,但是得到的价格小数没有经过处理。如果TokenB的小数位数远大于TokenA的小数位数,那么在计算预期可兑换TokenB数量时会出现偏差,amountFromOracle = priceA * swapAmountA / priceB会比预期小。

6. 同时,在大多数攻击中,预言机获取的TokenA和TokenB的价格是相等的,说明预言机获取的价格是错误的。

7. 因此,攻击者操纵Pangolin的代币数量,使Vee Finance的预言机刷新价格。这直接导致合约在滑点检查时从oracle获取错误的价格,从而导致滑点检查被绕过。

解决方案

1.采用chainlink预言机而不是又单一dex来定价

2.预言机得到代币价格后,要统一小数处理,避免略过滑点检测

Last updated