The new cancelUnstake() function allows users to cancel their unstaking, by taking the user's drafts and minting it again.
However, since the _payoutRewards() isn't being called this means that the user would get rewards for the period between the last time _payoutRewards() was called and the time of cancellation.
Impact
Users would get rewards they don't deserve, at the expense of other stakers.
Proof of Concept
cancelUnstake() doesn't call _payoutRewards(), this means that the minting part would be done with the old staking rate.
Using an old staking rate means that the user would get a share of the rewards since the last time _payoutRewards() was called.
Lines of code
https://github.com/reserve-protocol/protocol/blob/c4ec2473bbcb4831d62af55d275368e73e16b984/contracts/p1/StRSR.sol#L341-L380
Vulnerability details
The new
cancelUnstake()
function allows users to cancel their unstaking, by taking the user's drafts and minting it again. However, since the_payoutRewards()
isn't being called this means that the user would get rewards for the period between the last time_payoutRewards()
was called and the time of cancellation.Impact
Users would get rewards they don't deserve, at the expense of other stakers.
Proof of Concept
cancelUnstake()
doesn't call_payoutRewards()
, this means that the minting part would be done with the old staking rate. Using an old staking rate means that the user would get a share of the rewards since the last time_payoutRewards()
was called.Recommended Mitigation Steps
Call
_payoutRewards()
before the mintingAssessed type
Other