Permanent funds lock in StargateRewardableWrapper
#27
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
M-05
primary issue
Highest quality submission among a set of duplicates
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
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
The text was updated successfully, but these errors were encountered: