【漏洞分析】20250105-SorraStaking:奖励金额计算错误,每次取款都有大收益
背景信息
2024-12-21 11:58:11 (UTC)
2025-01-04 11:59:23 (UTC)
- 攻击交易 1:
https://app.blocksec.com/explorer/tx/eth/0x6439d63cc57fb68a32ea8ffd8f02496e8abad67292be94904c0b47a4d14ce90d - 攻击交易 2:
https://app.blocksec.com/explorer/tx/eth/0xf1a494239af59cd4c1d649a1510f0beab8bb78c62f31e390ba161eb2c29fbf8b - 攻击交易 3:
https://app.blocksec.com/explorer/tx/eth/0x09b26b87a91c7aea3db05cfcf3718c827eba58c0da1f2bf481505e0c8dc0766b
漏洞合约:
https://vscode.blockscan.com/ethereum/0x5d16b8ba2a9a4eca6126635a6ffbf05b52727d50
sorraStaking
项目是一个质押奖励项目,用户质押 SOR 代币并锁定一段时间,解锁后获取 SOR 代币作为奖励。
Trace 分析
准备交易
在 2024-12-21 11:58:11 (UTC),攻击者进行了一笔
deposit
操作。
攻击交易
由于三笔攻击交易类似,所以只分析其中一笔。
在
deposit
操作的 13 天后,攻击者进行了后续的攻击操作。攻击者反复调用
withdraw
函数,虽然每次只取回
_amount = 1
的代币,但是能够获得大量的奖励代币。
然后将获得的 SOR 代币进行出售,最后支付 bundler 的费用。
代码分析
当用户执行
deposit
进行质押时,合约收取质押代币,并记录仓位
deposite → _updatePosition → _increasePosition
_increasePosition
函数记录质押的数量,时间和利率等相关信息。
在
withdraw
函数中,会先计算用户的奖励代币数量
rewardAmount
,然后将
(_amount + rewardAmount)
一同发给用户。
通过
_calculateRewards
函数来计算奖励金额。
代码问题:
- 每次所领取的奖励金额都是按照用户质押的总金额来计算的,而不是当前取款数额对应的奖励金额。
withdraw
函数可以将质押金额进行分批提取。
所以攻击者通过多次调用
withdraw
函数来赎回部分质押代币,却每次都能获取到对应所有质押金额的奖励代币,最终获得超额的收益。