Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: low
Invalid

Wrong lastClaimTime update in BaseGuage.sol::getReward()

Summary

The lastClaimTime for the user will be updated even if the user has no reward, so he has to wait 24hours for the next try.

function getReward() external virtual nonReentrant whenNotPaused updateReward(msg.sender) {
if (block.timestamp - lastClaimTime[msg.sender] < MIN_CLAIM_INTERVAL) {
revert ClaimTooFrequent();
}
// @audit lastClaimTime should be updated only if you have reward.
// otherwise 1second later i could have a reward, but i must wait until tomorrow.
lastClaimTime[msg.sender] = block.timestamp;
UserState storage state = userStates[msg.sender];
uint256 reward = state.rewards;
if (reward > 0) {
state.rewards = 0;
uint256 balance = rewardToken.balanceOf(address(this));
if (reward > balance) {
revert InsufficientBalance();
}
rewardToken.safeTransfer(msg.sender, reward);
emit RewardPaid(msg.sender, reward);
}
}

Vulnerability Details

If a user calls getReward() when they have no pending reward, their lastClaimTime is updated anyway.
If they get a reward just seconds later, they must wait 24 hours.
This is not good approach since the users can get frustrated.

Impact

Users are unfairly penalized. They must wait for the 24 hours to pass even if they didn't get any reward.

Tools Used

Manual

Recommendations

Consider updating the lastClaimTime for the user only if they have rewards to claim.

function getReward() external virtual nonReentrant whenNotPaused updateReward(msg.sender) {
if (block.timestamp - lastClaimTime[msg.sender] < MIN_CLAIM_INTERVAL) {
revert ClaimTooFrequent();
}
// @audit lastClaimTime should be updated only if you have reward.
// otherwise 1second later i could have a reward, but i must wait until tomorrow.
- lastClaimTime[msg.sender] = block.timestamp;
UserState storage state = userStates[msg.sender];
uint256 reward = state.rewards;
if (reward > 0) {
state.rewards = 0;
+ lastClaimTime[msg.sender] = block.timestamp;
uint256 balance = rewardToken.balanceOf(address(this));
if (reward > balance) {
revert InsufficientBalance();
}
rewardToken.safeTransfer(msg.sender, reward);
emit RewardPaid(msg.sender, reward);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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