零时科技 || Ramses 攻击事件分析
背景介绍
近期,我们监测到一次 Arbitrum 链上攻击事件,
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb
被攻击的项目是 Ramses Exchange ,攻击总造成约 27 ETH 的损失,约为 70,000 USD 。Ramses是在 Arbitrum 上推出的新型去中心化自动做市商 (AMM) 。该协议通过 RAM 代币和 veNFT 运行。
攻击及事件分析
本次攻击共分为两笔交易,第一笔交易为前置的操作,交易hash为:
https://arbiscan.io/tx/0xa0795952a09f4aeaacf0abb213dedeaa7b7dd71c04eaa3fd22db33957e1c724c,我们称为交易A;
第二笔交易为正式的攻击交易,交易hash为
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb,我们称为交易B。
交易A的主要行为:
首先,攻击者将 0.0001 ETH 利用 deposit 兑换成 WETH,
随后,攻击者使用 0.0001 WETH 使用 Ramses Exchange 兑换成 RAM。
最后,攻击者利用 create_lock 将 1 RAM 锁定,并获得一个 id 为 18785 的 veNFT (在攻击时会用到),作为锁定凭证。
交易B的主要行为:
攻击者首先查看了 Ramses Exchange 所有池子的 WETH 余额,
接着,利用闪电贷从 uniswapV3 上贷了 12.2 WETH,
随后,攻击者利用 Ramses 的Bribe机制向每个池子转入与之 WETH 余额相等的 WETH (为了后面将池子中所有的 WETH 取出)。
然后,攻击者通过 vote 给对应的交易池投票,
接着,攻击者通过 getPeriodReward 获取投票的激励,
我们看一下 getPeriodReward 的具体实现,
由于攻击者在攻击交易A中,获得了id为18785的veNFT,所以IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, 18785) 为true。接着,可以看到_getReward的代码如下:
随后,攻击者利用 reset 撤回针对上述交易池的投票。
接着,再利用 split 将 id 为 18785 的 veNFT 其中 lock 的 0.99999 RAM 分割出一个的 id 为18787 的新的 veNFT 。漏洞就出在这里,当攻击者利用 split 分割出一个新的 veNFT 时,又可以利用对应 lock 的 RAM 进行投票,获取奖励,没有验证这笔 lock 的资金是否已经领取过奖励。所以攻击者可以重复利用 reset 重置投票,再利用 split 分割出一个新的 veNFT ,再利用 vote投票,最后用 getPeriodReward 获取投票的奖励。
攻击者针对 USDC 和 ARB 对应的交易对同样实施了相同的攻击。
总结
本次漏洞的成因是在 Ramses Exchange 在发放 lock RAM 对应的奖励时,没有验证这笔lock的资金是否已经领过奖励。导致攻击者可以利用 reset 和 split 切分 veNFT 重复领取奖励。建议项目方在设计经济模型和代码运行逻辑时要多方验证,合约上线前审计时尽量选择多个审计公司交叉审计。