思路验证
让我们通过攻击者的操作来验证此过程是否如我们所想:
1、首先在保险期限内是肯定的
2、攻击者传入的 vaultToExerciseFrom 分别为:
0xe7870231992ab4b1a01814fa0a599115fe94203f0x076c95c6cd2eb823acc6347fdf5b3dd9b83511e4
经验证,这两个地址都创建了 vault
3、攻击者调用 exercise 传入 oTokensToExercise 为 0x1443fd000 (5440000000),msg.value 为 272ETH,vaultsToExerciseFrom 分别为以上两个地址
4、此时由于此前攻击者创建的 oToken 为 0xa21fe800 (2720000000),及 vault.oTokensIssued 为 2720000000 小于 5440000000,所以将走 exercise 函数中的 else 逻辑,此时 oTokensToExercise 为 0xa21fe800 (2720000000),则以上代码第 60 行 msg.value == amtUnderlyingToPay 是肯定成立的
5、由于 vaultsToExerciseFrom 传入两个地址,所以 for 循环将执行两次 _exercise 函数,因此将 transfer 两次把 USDC 转给攻击者合约
完整的攻击流程如下
1、攻击者使用合约先调用 Opyn 合约的 createERC20CollateralOption 函数创建 oToken
2、攻击合约调用 exercise 函数,传入已创建 vault 的地址
3、通过 exercise 函数中 for 循环逻辑执行调用两次 _exercise 函数
4、exercise 函数调用 transferCollateral 函数将 USDC 转给函数调用者(由于 for 循环调用两次 _exercise 函数,transferCollateral 函数也将执行两次)
5、攻击合约调用 removeUnderlying 函数将此前传入的 ETH 转出
6、最终攻击者拿回了此前投入的 ETH 以及额外的 USDC
攻击合约地址
0xe7870231992Ab4b1A01814FA0A599115FE94203f
Opyn 合约地址
0x951D51bAeFb72319d9FBE941E1615938d89ABfe2
攻击交易(其一)
0xa858463f30a08c6f3410ed456e59277fbe62ff14225754d2bb0b4f6a75fdc8ad
修复建议
此次攻击主要是利用了 _exercise 函数中对 vaultToExerciseFrom 是否创建 vault 的检查缺陷。此检查未校验 vaultToExerciseFrom 是否是调用者自己,而只是简单的检查是否创建了 vault,导致攻击者可以任意传入已创建 vault 的地址来通过检查。
建议如下:
1、在处理用户可控的参数时应做好权限判断,限制 vaultToExerciseFrom 需为调用者本人。
2、项目方可以在项目初期或未完成多次严谨安全审计之前添加合约暂停功能与可升级模型,避免在发生黑天鹅事件时无法有效的保证剩余资金安全。
版权声明:项目均采集于互联网, 戴诗东 无法审核全面,且希望大家能赚钱,请谨慎切勿上当受骗!
温馨提示:★★★天上真会掉馅饼!天道酬勤,都是机会!不错过每个空投糖果!真假难以辨认,尽量0撸!