Raisebox Faucet

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

The `claimFaucetTokens::lastDripDay` and `claimFaucetTokens::lastFaucetDripDay` storage variables are not updated correctly, which may lead to confusion and misinterpretation of the last drip day and last faucet drip day.

Root + Impact

Description

The claimFaucetTokens::lastDripDay variable stores an index from the epoch, which advances based on a precise timestamp, making it more accurate. On the other hand, the claimFaucetTokens::lastFaucetDripDay variable is stored as a raw timestamp and is used to reset dailyClaimCount after 24 hours from the precise timestamp. This causes a difference between the last drip day and the last faucet drip day.

function claimFaucetTokens() public {
...
// drip sepolia eth to first time claimers if supply hasn't ran out or sepolia drip not paused**
// still checks
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
uint256 currentDay = block.timestamp / 24 hours;
if (currentDay > lastDripDay) {
lastDripDay = currentDay;
dailyDrips = 0;
// dailyClaimCount = 0;
}
...
/**
*
* @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;
}
...
}

Risk

Likelihood:

  • The difference begins on the next day after the first claim.

Impact:

  • Confusion and misinterpretation of the last drip day and last faucet drip day creating difference of the last drip day and last faucet drip day.

Proof of Concept

Add the following code snippet to the RaiseBoxFaucet.t.sol test file.

This code snippet is designed to demonstrate the claimFaucetTokens::lastDripDay and claimFaucetTokens::lastFaucetDripDay storage variables show different values after 24 hours.

function testCheckLastFaucetDripDayAndLastDripDayDifferenceAfter24Hours() public {
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
console.log("Day 1 claim");
uint256 firstLastDripDay = raiseBoxFaucet.lastDripDay() * 24 hours;
uint256 firstLastFaucetDripDay = raiseBoxFaucet.lastFaucetDripDay();
console.log("Last drip day: ", firstLastDripDay);
console.log("Last faucet drip day: ", firstLastFaucetDripDay);
vm.warp(block.timestamp + 1 days);
console.log("\n");
console.log("Day 2 claim");
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
uint256 secondLastDripDay = raiseBoxFaucet.lastDripDay() * 24 hours;
uint256 secondLastFaucetDripDay = raiseBoxFaucet.lastFaucetDripDay();
console.log("Last drip day: ", secondLastDripDay);
console.log("Last faucet drip day: ", secondLastFaucetDripDay);
assertEq(
firstLastDripDay, firstLastFaucetDripDay, "At first claim, last drip day is equal to last faucet drip day"
);
assertNotEq(
secondLastDripDay,
secondLastFaucetDripDay,
"At second claim, last drip day is not equal to last faucet drip day"
);
}

Recommended Mitigation

Update the claimFaucetTokens::lastFaucetDripDay storage variable correctly.

- if (block.timestamp > lastFaucetDripDay + 1 days) {
- lastFaucetDripDay = block.timestamp;
- dailyClaimCount = 0;
- }
+ uint256 currentFaucetDripDay = block.timestamp / 24 hours;
+
+ if (currentFaucetDripDay > lastFaucetDripDay) {
+ lastFaucetDripDay = currentFaucetDripDay;
+ dailyClaimCount = 0;
+ }
Updates

Lead Judging Commences

inallhonesty Lead Judge 13 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.