Raisebox Faucet

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

Inconsistent Daily Reset Logic

Description

The contract uses two different methods for daily resets: block.timestamp / 24 hours for ETH drips (lastDripDay) and block.timestamp > lastFaucetDripDay + 1 days for token claims (dailyClaimCount). This inconsistency can cause misaligned resets, leading to scenarios where ETH or token claims are blocked unexpectedly.

// Root cause in the codebase with @> marks to highlight the relevant section
function claimFaucetTokens() public {
// ... ETH drip reset ...
@>uint256 currentDay = block.timestamp / 24 hours;
if (currentDay > lastDripDay) {
lastDripDay = currentDay;
dailyDrips = 0;
}
// ... token claim reset ...
@>if (block.timestamp > lastFaucetDripDay + 1 days) {
@> lastFaucetDripDay = block.timestamp;
@> dailyClaimCount = 0;
@>}
}

Risk

Likelihood:

  • Occurs when the two reset mechanisms trigger at different times due to their differing calculations.

  • Occurs during claims near the boundary of a 24-hour period.

Impact:

  • Users may be able to claim tokens but not ETH (or vice versa), causing inconsistent behavior.

  • Disrupts the faucet’s reliability for testnet interactions.

Proof of Concept

Explanation: The PoC demonstrates how the different reset mechanisms can lead to inconsistent behavior. After a claim sets both counters, advancing time to just before a full day triggers the ETH reset but not the token reset, causing a claim to fail for tokens but succeed for ETH.

function testInconsistentReset(RaiseBoxFaucet faucet) public {
vm.prank(user);
faucet.claimFaucetTokens(); // Sets lastDripDay and lastFaucetDripDay
vm.warp(block.timestamp + 23 hours + 59 minutes); // Just before 1 day
// ETH reset occurs (block.timestamp / 24 hours), but token reset doesn’t
vm.prank(user);
faucet.claimFaucetTokens(); // May fail for tokens but succeed for ETH
}

Recommended Mitigation

Explanation: We standardize the reset logic to use block.timestamp / 24 hours for both ETH and token claims, ensuring both counters reset at the same time. This eliminates misalignment and ensures consistent claim behavior.

function claimFaucetTokens() public {
+ uint256 currentDay = block.timestamp / 24 hours;
if (currentDay > lastDripDay) {
lastDripDay = currentDay;
dailyDrips = 0;
}
- if (block.timestamp > lastFaucetDripDay + 1 days) {
- lastFaucetDripDay = block.timestamp;
- dailyClaimCount = 0;
- }
+ if (currentDay > lastFaucetDripDay) {
+ lastFaucetDripDay = currentDay;
+ dailyClaimCount = 0;
+ }
}
Updates

Lead Judging Commences

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

Inconsistent day calculation methods cause desynchronization between ETH and token daily resets.

Support

FAQs

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