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

NatSpec in `FjordStaking::unstake` and `FjordStaking::unstakeVested` is apparently incorrect, leading to wrong assumptions about functions

Vulnerability Details

The NatSpec documentation for FjordStaking::unstake and FjordStaking::unstakeVested indicates that the function claims the rewards and also additionally it is also mentioned that _isClaimEarly if set to true than they can withdraw the rewards beforehand. But these functions just handle the unstaking of the staked tokens where just the tokens of the users are unstaked.This leads us to conclude that the vulnerability stems from incorrect NatSpec documentation. However, this conclusion should be verified by the protocol development team.

/// @notice Unstake FJORD tokens from the contract.
/// @dev This function allows users to unstake a certain number of FJORD tokens,
@> /// while also claiming all the pending rewards. If _isEarly is true then the
@> /// user will be able to bypass rewards cooldown of 3 epochs and claim early,
@>/// but will incur early claim penalty.
/// @param _epoch The epoch cycle from which user wants to unstake.
/// @param _amount The amount of tokens user wants to unstake.
/// @return total The total amount sent to the user.
function unstake(
uint16 _epoch,
uint256 _amount
) external checkEpochRollover redeemPendingRewards returns (uint256 total) {
if (_amount == 0) revert InvalidAmount();
DepositReceipt storage dr = deposits[msg.sender][_epoch];
.........
/// @notice Unstake vested FJORD tokens from the contract.
/// @dev This function allows users to unstake vested FJORD tokens,
@> /// while also claiming all the pending rewards. If _isClaimEarly is true then the
@> /// user will be able to bypass rewards cooldown of 3 epochs and claim early,
@> /// but will incur early claim penalty.
/// @param _streamID The sablier streamID that the user staked.
function unstakeVested(
uint256 _streamID
) external checkEpochRollover redeemPendingRewards {
//CHECK
NFTData memory data = _streamIDs[msg.sender][_streamID];
DepositReceipt memory dr = deposits[msg.sender][data.epoch];
..............

Impact

The incorrect NatSpec documentation in the FjordStaking::unstake and FjordStaking::unstakeVested functions could lead to significant confusion for users,developers and auditors relying on the documentation to understand the protocol's behavior. The documentation suggests that these functions handle both unstaking and claiming rewards, with an additional option to claim rewards early when _isClaimEarly is set to true. However, the functions only perform the unstaking of tokens without managing reward claims.

Tools Used

Manual

Recommendations

/// @notice Unstake FJORD tokens from the contract.
/// @dev This function allows users to unstake a certain number of FJORD tokens,
- /// while also claiming all the pending rewards. If _isEarly is true then the
- /// user will be able to bypass rewards cooldown of 3 epochs and claim early,
- /// but will incur early claim penalty.
/// @param _epoch The epoch cycle from which user wants to unstake.
/// @param _amount The amount of tokens user wants to unstake.
/// @return total The total amount sent to the user.
function unstake(
uint16 _epoch,
uint256 _amount
) external checkEpochRollover redeemPendingRewards returns (uint256 total) {
if (_amount == 0) revert InvalidAmount();
DepositReceipt storage dr = deposits[msg.sender][_epoch];
.........
/// @notice Unstake vested FJORD tokens from the contract.
/// @dev This function allows users to unstake vested FJORD tokens,
- /// while also claiming all the pending rewards. If _isClaimEarly is true then the
- /// user will be able to bypass rewards cooldown of 3 epochs and claim early,
- /// but will incur early claim penalty.
/// @param _streamID The sablier streamID that the user staked.
function unstakeVested(
uint256 _streamID
) external checkEpochRollover redeemPendingRewards {
//CHECK
NFTData memory data = _streamIDs[msg.sender][_streamID];
DepositReceipt memory dr = deposits[msg.sender][data.epoch];
..............
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!