DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: high
Invalid

FjordStaking: Normal users cant use stakeVested

Summary

The function stakeVested in the contract FjordStaking.sol allows users to stake a sablier stream. Some streams can be canceled. Therefore the contract only allows authorizedSablierSenders to stake with such streams. The respecttive check is inside the stakeVested function here. But the check has a mistake and does not allow normal users to stake any stream.

Vulnerability Details

The check in stakeVested reverts with StreamNotSupported if the sender of the stream is not set as part of the authorizedSablierSenders. But this check should only revert if the stream's sender is not set as part of the authorizedSablierSenders only if the stream can be canceled.

Impact

Users can not use the stakeVested function and therefor can not stake any vesting streams.

Tools Used

manual review

POC

Run this test inside the existing stakeVested.t.sol test:

function test_poc() public {
uint256 streamID = createStream(alice, token, false, 100 ether);
assertEq(ISablierV2Lockup(fjordStaking.sablier()).isCancelable(streamID), false);
vm.startPrank(alice);
SABLIER.approve(address(fjordStaking), streamID);
fjordStaking.stakeVested(streamID);
vm.stopPrank();
}

It will revert with StreamNotSupported, even though the stream is not cancelable.

Recommendations

Only check if the stream sender is set in the authorizedSablierSenders if the stream is cancelable. This can be checked with sablier.isCancelable(_streamID). Full diff:

--- a/FjordStaking.sol.orig
+++ b/FjordStaking.sol
@@ -400,7 +400,7 @@ contract FjordStaking is ISablierV2LockupRecipient {
if (sablier.isCold(_streamID)) revert NotAWarmStream();
// only allow authorized stream sender to stake cancelable stream
- if (!authorizedSablierSenders[sablier.getSender(_streamID)]) {
+ if (sablier.isCancelable(_streamID) && !authorizedSablierSenders[sablier.getSender(_streamID)]) {
revert StreamNotSupported();
}
if (address(sablier.getAsset(_streamID)) != address(fjordToken)) revert InvalidAsset();
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.