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 {
...
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
uint256 currentDay = block.timestamp / 24 hours;
if (currentDay > lastDripDay) {
lastDripDay = currentDay;
dailyDrips = 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:
Impact:
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;
+ }