Open code423n4 opened 1 year ago
thereksfour changed the severity to 2 (Med Risk)
thereksfour marked the issue as primary issue
External requirement with specific owner behavior.
tbrent marked the issue as sponsor confirmed
thereksfour marked the issue as satisfactory
thereksfour marked the issue as selected for report
Lines of code
https://github.com/reserve-protocol/protocol/blob/9ee60f142f9f5c1fe8bc50eef915cf33124a534f/contracts/plugins/assets/stargate/StargateRewardableWrapper.sol#L48
Vulnerability details
Impact
The staked funds might be locked because the deposit/withdraw/transfer logic reverts.
Proof of Concept
In
StargateRewardableWrapper
,_claimAssetRewards()
claims the accumulated rewards from the staking contract and it's called during every deposit/withdraw/transfer in _beforeTokenTransfer() and _claimAndSyncRewards().And in the stargate staking contract, deposit() calls updatePool() inside the function.
The problem is
updatePool()
reverts whentotalAllocPoint == 0
and this value can be changed by stargate admin using set().So user funds might be locked like the below.
totalAllocPoint = 10
.StargateRewardableWrapper
, some users staked their funds using deposit().totalAllocPoint = 0
now. In the stargate contract, it's not so critical because this contract has emergencyWithdraw() to rescue funds without caring about rewards. Normal users can withdraw their funds using this function.StargateRewardableWrapper
, there is no logic to be used under the emergency and deposit/withdraw won't work because_claimAssetRewards()
reverts in updatePool() due to 0 division.Tools Used
Manual Review
Recommended Mitigation Steps
We should implement a logic for an emergency in
StargateRewardableWrapper
.During the emergency,
_claimAssetRewards()
should return 0 without interacting with the staking contract and we should usestakingContract.emergencyWithdraw()
to rescue the funds.Assessed type
Error