Closed sherlock-admin2 closed 1 year ago
3 comment(s) were left on this issue during the judging contest.
Trumpero commented:
invalid, tx will revert if transfer fails
darkart commented:
Transaction will revert on safetransfer failing so no loss
YakuzaKiawe commented:
invalid as the function is storing the balance in memory and using that in safeTransfer not from the array from which the function subtracted the amount
mrvincere
high
GPToke Rewards Collection Can Lead to Massive Loss of User Funds
Summary
The GPToke staking contract contains a critical bug in the
_collectRewards()
internal function that could lead to irrecoverable loss of user funds. If the reward transfer fails for any reason, a user'sunclaimedRewards
balance is reset before the transfer occurs, resulting in potentially unlimited rewards being lost. This poses a major risk to user funds and trust in the platform.Vulnerability Detail
The
_collectRewards()
function first calculates any pending rewards due to the user, which includes:netRewardPerShare * balance
)unclaimedRewards
amount from previous cyclesIt then proceeds to:
1. Reset
unclaimedRewards
to 02. Emit
RewardsClaimed
event3. Update
totalRewardClaimed
and per-user totals4. Finally, it calls
weth.safeTransfer()
to send the pending rewards to the userThe critical issue is that steps 1-3 above occur before the rewards are transferred. This means if the
weth.safeTransfer
call fails for any reason, the user'sunclaimedRewards
balance is wiped. This permanently destroys any record of those pending rewards.For example:
unclaimedRewards
collectRewards()
, which calculates 50 WETH in new pending rewards_collectRewards()
resets Alice'sunclaimedRewards
to 0, losing the 100,000 WETH recordweth.safeTransfer
call fails due to gas limitsThe contract meanwhile acts as if the rewards were successfully sent, creating a critical inconsistency in the platform's accounting.
This can occur any time the rewards transfer fails, due to:
With no limit on unclaimed reward accrual over long durations, the potential loss amounts are essentially unlimited.
Impact
Code Snippet
https://github.com/sherlock-audit/2023-06-tokemak/blob/main/v2-core-audit-2023-07-14/src/staking/GPToke.sol#L267C5-L316C6
Tool used
Manual Review
Recommendation
To address this, the
unclaimedRewards
reset and state changes should occur after the rewards transfer: