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

`completeClaimReques` fn doesn't update the `lastClaimedEpoch` after claiming rewards

Vulnerability Details

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();
//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);
}

in the completeClaimRequest function:

The function doesn't update the userData[msg.sender].lastClaimedEpoch after claiming rewards. This could lead to a situation where a user can claim rewards multiple times for the same epochs if they wait long enough between claims.

Additionally, there's no check to ensure that the claim request epoch is greater than the user's last claimed epoch. This could potentially allow a user to claim rewards for epochs they've already claimed.

To fix this, the function should:

  1. Check if cr.requestEpoch > userData[msg.sender].lastClaimedEpoch

  2. Update userData[msg.sender].lastClaimedEpoch = currentEpoch after successful claim

These changes would ensure that users can only claim rewards once per epoch range and prevent potential reward duplication.

Impact

  1. User stakes tokens and accumulates rewards over several epochs.

  2. User calls claimReward(false) to create a claim receipt for epoch X.

  3. User waits for 3+ epochs (satisfying the cooldown period).

  4. User calls completeClaimRequest(), receiving rewards up to epoch X+3.

  5. User waits for another 3+ epochs without staking or unstaking.

  6. User calls claimReward(false) again, creating a new claim receipt for the current epoch.

  7. After 3 more epochs, user calls completeClaimRequest() again.

In step 7, the user would receive rewards for epochs that were already claimed in step 4, because the function doesn't update lastClaimedEpoch or check against it.

IMPACT: This bug could allow users to claim more rewards than they're entitled to, potentially draining the contract of excess rewards and disrupting the economic balance of the staking system.

To fix this, implement the suggested checks and updates to lastClaimedEpoch.

Tools Used

Manual review

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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