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

Potential Delay in Reward Claim Due to Epoch-Based Time Calculation in FjordPoint Contract

Summary

The use of epoch-based time calculations, instead of block.timestamp, for claiming rewards in the FjordPoint satking contract can result in significant delays for users. Specifically, this delay can extend beyond 21 days, forcing users to wait up to 27 days or more before they can successfully claim their rewards. This issue effectively creates a denial of service (DoS) scenario, as users are unable to access their rewards in a timely manner.

https://codehawks.cyfrin.io/c/2024-08-fjord#:~:text=Penalised Staker%3A a Staker that claim rewards before 3 epochs or 21 days.

Vulnerability Details

The use of epoch-based time calculations, instead of `block.timestamp`, for claiming rewards in the FjordPoint contract can result in significant delays for users. Specifically, this delay can extend beyond 21 days, forcing users to wait up to 27 days or more before they can successfully claim their rewards. This issue effectively creates a denial of service (DoS) scenario, as users are unable to access their rewards in a timely manner.

In the FjordPoint contract, the reward distribution mechanism relies on the epoch system, which calculates the current epoch based on a predefined epoch duration. The function `distributePoints()` checks whether the current `block.timestamp` is greater than the last distribution time plus the epoch duration:

function distributePoints() public {
@audit >>>> if (block.timestamp < lastDistribution + EPOCH\_DURATION) {
return;
}
}

Similarly, in the staking contract, users must wait for a minimum of three epochs before they can complete the claim receipt process:

// To complete claim receipt, user must wait for at least 3 epochs
@audit >>>> if (currentEpoch - cr.requestEpoch <= claimCycle) revert CompleteRequestTooEarly();

When a user initiates a claim, the `requestEpoch` is set to the current epoch:

if (!_isClaimEarly) {
@audit >>>> claimReceipts[msg.sender] = ClaimReceipt({ requestEpoch: currentEpoch, amount: ud.unclaimedRewards });
}

The current epoch is determined using the following function:

function getEpoch(uint256 _timestamp) public view returns (uint16) {
if (_timestamp < startTime) return 0;
return uint16((_timestamp - startTime) / epochDuration) + 1;
}

This setup can lead to an extended delay in the ability to claim rewards.

For example, if a user initiates a claim at the beginning of epoch 2, t

hey will have to wait for at least 3 epochs (21 days) to withdraw.

However, due to the specific timing requirements, the user might be forced to wait an additional 6 days, resulting in a total delay of 27 days and 59 minutes and 59 seconds before the claim can be processed without reverting.

Impact

This vulnerability creates a denial of service (DoS) condition for users, as it prevents them from claiming their rewards within the expected timeframe. The forced waiting period can extend up to 28 days beyond the intended duration

Tools Used

Manual Code Review

Recommendations

1. **Replace Epoch-Based Timing with Block Timestamps**: Consider using `block.timestamp` for determining the eligibility to claim rewards. This approach is more precise and can reduce the unnecessary delay caused by epoch increments.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
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.