Raisebox Faucet

First Flight #50
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

`DailyClaimCount` not reset properly blocking permanently the protocol when `DailyClaimLimit` is reached

DailyClaimCount not reset properly blocking permanently the protocol when DailyClaimLimit is reached

Description

Each time someone claims a drip, the DailyClaimCount is incremented at the end of the function claimFaucetTokens.

lastClaimTime[faucetClaimer] = block.timestamp;
dailyClaimCount++;

Also at the end of claimFaucetTokens, the DailyClaimCount is reset when a new day arises.

/**
*
* @param lastFaucetDripDay tracks the last day a claim was made
* @notice resets the @param dailyClaimCount every 24 hours
*/
if (block.timestamp > lastFaucetDripDay + 1 days) {
lastFaucetDripDay = block.timestamp;
dailyClaimCount = 0;
}

And if the DailyClaimCount reached DailyClaimLimit, the condition at the start of the function will block any new user until the next day.

if (dailyClaimCount >= dailyClaimLimit) {
revert RaiseBoxFaucet_DailyClaimLimitReached();
}

The problem here is that the condition for DailyClaimCount's reset is after the condition to block new users if DailyClaimLimit is reached.

If the DailyClaimLimit is reached before the end of the day, the protocol is blocked by the dailyClaimCount >= dailyClaimLimit condition and the function is permanently blocked for every user.

Risk

Likelyhood(High) : A free drip will attract a lot of users every day; 100 users possible for a single day.
Impact(High) : The claimFaucetTokens is permanently blocked, causing the core functionality of the protocol to stop.

Proof of Concept

Add this test to RaiseBoxFaucet.t.sol :

function testDailyCount() public {
address randomUser;
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
// 99 randomUsers claim drips
for(uint256 i = 1; i < 100; i++) {
randomUser = vm.addr(i);
vm.prank(randomUser);
raiseBoxFaucet.claimFaucetTokens();
}
assertEq(raiseBoxFaucet.dailyClaimCount(), 100);
// Revert because dailyClaimLimitReached
vm.expectRevert();
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
// 10 days passed
vm.warp(block.timestamp + 10 days);
// User2 still can't claim a drip because dailyClaimCount couldn't be reset properly
vm.expectRevert();
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
}

Recommended Mitigation

Change the position of the DailyClaimCount's reset, it should be before the dailyClaimCount >= dailyClaimLimit condition.

function claimFaucetTokens() public {
...
/**
*
* @param lastFaucetDripDay tracks the last day a claim was made
* @notice resets the @param dailyClaimCount every 24 hours
*/
if (block.timestamp > lastFaucetDripDay + 1 days) {
lastFaucetDripDay = block.timestamp;
dailyClaimCount = 0;
}
...
if (dailyClaimCount >= dailyClaimLimit) {
revert RaiseBoxFaucet_DailyClaimLimitReached();
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 11 days ago
Submission Judgement Published
Validated
Assigned finding tags:

dailyClaimCount Reset Bug

Support

FAQs

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