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

Denial of Service (DoS) When Completing Claim Request for Epoch at Index 1

Summary

See below

Vulnerability Details

The completeClaimRequest function in the smart contract is intended to allow users to finalize a claim receipt from a specific epoch after waiting for a set number of epochs (claimCycle). However, due to the logic in the function and the initial setting of currentEpoch in the constructor, the function creates a Denial of Service (DoS) vulnerability when users attempt to complete a claim request for an epoch at index 1.
Constructor Snippet:

constructor() {
currentEpoch = 1;
// Other initialization logic
}

completeClaimRequest Function Snippet:

/// @notice Comaplete claim receipt from specific epoch.
/// @dev This function allows users to complete claim receipt from an epoch
/// @return rewardAmount The reward amount that has been distributed.
function completeClaimRequest()
external
checkEpochRollover
redeemPendingRewards
returns (uint256 rewardAmount)
{
ClaimReceipt memory cr = claimReceipts[msg.sender];
//CHECK
if (cr.requestEpoch < 1) revert ClaimReceiptNotFound();
// to complete claim receipt, user must wait for at least 3 epochs
if (currentEpoch - cr.requestEpoch <= claimCycle) revert CompleteRequestTooEarly(); // @audit
//EFFECT
rewardAmount = cr.amount;
userData[msg.sender].unclaimedRewards -= rewardAmount;
totalRewards -= rewardAmount;
delete claimReceipts[msg.sender];
//INTERACT
fjordToken.safeTransfer(msg.sender, rewardAmount);
emit RewardClaimed(msg.sender, rewardAmount);
}

From the constructor, currentEpoch is initialized to 1, which means that the contract starts at the first epoch by default. When the completeClaimRequest function is called, the function first validates that the requestEpoch in the user's ClaimReceipt is not less than 1. Then, it checks whether the difference between currentEpoch and cr.requestEpoch is greater than claimCycle. If the difference is less than or equal to claimCycle, the function reverts with the CompleteRequestTooEarly() error.

When both currentEpoch and cr.requestEpoch are 1, the difference between them is 0. Since 0 <= claimCycle is always true (assuming claimCycle is a positive integer (obviuosly 3 uint8 public constant claimCycle = 3;)), the function will revert, making it impossible for a user to complete their claim request during the first epoch.

This is particularly problematic for users whose ClaimReceipt was generated in epoch 1, as they will be perpetually unable to complete their claim due to this logic.

Impact

This vulnerability results in a Denial of Service (DoS) condition, where users who have claims from epoch 1 cannot complete their claim request. This restricts access to their rewards, undermining the contract's intended functionality and potentially causing user dissatisfaction and loss of trust in the protocol.

Tools Used

Manual

Recommendations

The logic should be adjusted to exclude the first epoch from the CompleteRequestTooEarly check. This can be implemented by modifying the condition as follows:

if (currentEpoch > 1 && currentEpoch - cr.requestEpoch <= claimCycle) revert CompleteRequestTooEarly();
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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