The incorrect input argument of the function call FjordPoints#onUnstaked
in FjordStaking#_unstakeVested
will cause the vested stream is not unstaked successfully from FjordStaking
when a Sablier sender cancels a vested stream.
A Sablier sender can cancel a vested stream by calling SablierV2Lockup#cancel
, then the sablier
contract will call to FjordStaking#onStreamCanceled
FjordStaking#onStreamCanceled
will call to FjordStaking#_unstakeVested
and then FjordPoints#onUnstaked
https://github.com/Cyfrin/2024-08-fjord/blob/0312fa9dca29fa7ed9fc432fdcd05545b736575d/src/FjordStaking.sol#L561
But the input argument to the FjordPoints#onUnstaked(address user, uint256 amount)
is msg.sender
, which is the sablier
contract's address. This will cause a revert at the function call FjordPoints#onUnstaked
, because the sablier
contract is not staking any points, the correct user
input argument here should be streamOwner
. Since the sablier
contract wraps the callback in a try-catch block, the vested stream is cancelled successfully in the sablier
contract. However, in the FjordStaking
contract, the vested stream is still staked.
When a Sablier sender cancels a vested stream, the vested stream is not unstaked successfully from FjordStaking
, which causes the vested stream is still accruing staking rewards and Fjord points.
Manual Review.
Fix the input argument of the function call FjordPoints#onUnstaked
in FjordStaking#_unstakeVested
Indeed the `points.onUnstaked` should use the streamOwner instead of msg.sender as an input parameter. Impact: high - The vested stakers who got their streams canceled will keep on receiving rewards (points included) for the previously staked stream. Likelihood: low - whenever a Sablier stream sender decides to `cancel()` a recipient's stream
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.