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

Users will not wait for complete claimCycle before completing the claim

Summary

Based on the current implementation users will be able to claim in a shorter cycle than expected

Vulnerability Details

Currently in the claimReward function, users are not allowed to claim if they claimed in the last epoch because of the following check

// do not allow to claimReward while user have pending claimReceipt
// or user have claimed from the last epoch
if (
claimReceipts[msg.sender].requestEpoch > 0
|| claimReceipts[msg.sender].requestEpoch >= currentEpoch - 1
) revert ClaimTooEarly();

Based on the check it should revert with ClaimTooEarly if the requestEpoch is > 0 or if requestEpoch >= currentEpoch -1, The issue arises because if a user was to call this function the requestEpoch will be updated in the claim receipt as shown below

if (!_isClaimEarly) {
claimReceipts[msg.sender] =
ClaimReceipt({ requestEpoch: currentEpoch, amount: ud.unclaimedRewards });
emit ClaimReceiptCreated(msg.sender, currentEpoch);
return (0, 0);
}

Now on callint this function the claimReceipts is updated accordingly and the value of requestEpoch is also updated based on the requested epoch. The issue now arises when user decides to call completeClaimRequest after the claimCycle has passed. IF the request is to be processed successfully, the claimReceipt is deleted as shown below

delete claimReceipts[msg.sender];

What this does is to reset everything in the claimReceipt so the requestEpoch is now 0, Lets now focus on the second part of the check claimReceipts[msg.sender].requestEpoch >= currentEpoch - 1 which will be 0 >= currentEpoch - 1, this will always pass as 0 will always be less. This means that users will indeed be able to call claimReward even if they claimed from the last epoch based on this comment

// do not allow to claimReward while user have pending claimReceipt
// or user have claimed from the last epoch

When user now calls completeClaimRequest there is this check that is to ensure that the claimCycle has actually passed or else it will revert

if (currentEpoch - cr.requestEpoch <= claimCycle) revert CompleteRequestTooEarly();

Because user managed to bypass the check explained above and claimed right after, now they will always be able to claim sooner if they do subsequest claims which is not the intended behaviour, This means that the maximum wait time for claim period is now compromised.

Proof of Concept (POC)

  • A user claims rewards early for Epoch 1 by creating a claim receipt.

  • After completing the claim request, the user claims again for Epoch 2 immediately.

  • Since the receipt for Epoch 1 has been resolved and deleted, the user can now create a new receipt for Epoch 2.

  • The user is able to bypass the intended 3-epoch wait period by creating new receipts of subsequent epochs. This allows them to effectively complete claims for multiple epochs in a shorter timeframe than intended.

Impact

Users are able to claim in a shorter cycle that expected

Tools Used

manual review

Recommendations

Add robust checks that prevent users from calling claimReward if they have called from the last epoch based on this:

// or user have claimed from the last epoch
// do not allow to claimReward while user have pending claimReceipt
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

Appeal created

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