Raisebox Faucet

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

dailyDrips counter resets incorrectly when a previous claimer reclaims, bypassing daily Sepolia ETH cap

Author Revealed upon completion

dailyDrips is reset for repeat ETH claimers , allowing the daily ETH cap (dailySepEthCap) to be bypassed.

Description

  • Each user can claim a fixed amount of faucet tokens and, if they have not claimed ETH before, a small amount of Sepolia ETH.

  • The contract resets dailyDrips = 0 whenever a user who has already claimed ETH calls claimFaucetTokens().

// Root cause in the codebase with @> marks to highlight the relevant section
function claimFaucetTokens() public {
....
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
uint256 currentDay = block.timestamp / 24 hours;
// finding how many days paseed in epoch
if (currentDay > lastDripDay) {
lastDripDay = currentDay;
dailyDrips = 0;
// dailyClaimCount = 0;
}
///////////// condition 1 /////////////////////////// //////////////// condition 2 /////////////////////////
if (dailyDrips + sepEthAmountToDrip <= dailySepEthCap && address(this).balance >= sepEthAmountToDrip) {
hasClaimedEth[faucetClaimer] = true;
dailyDrips += sepEthAmountToDrip;
(bool success,) = faucetClaimer.call{value: sepEthAmountToDrip}("");
if (success) {
emit SepEthDripped(faucetClaimer, sepEthAmountToDrip);
} else {
revert RaiseBoxFaucet_EthTransferFailed();
}
} else {
emit SepEthDripSkipped(
faucetClaimer,
address(this).balance < sepEthAmountToDrip ? "Faucet out of ETH" : "Daily ETH cap reached"
);
}
@> }else {
// @audit : Suppose a 3 drips has been done and then one person came who has claimed before then the dailyDrips should not be reset to 0
@> dailyDrips = 0;
}

Risk

Likelihood:

  • Users can trigger this whenever they have previously claimed ETH and call claimFaucetTokens() again.

  • Occurs even without malicious intent, simply by interacting with the faucet multiple times in a day.

Impact:

  • Daily ETH cap can be bypassed.

  • Faucet may run out of ETH faster than intended.

  • Misleading metrics for ETH distribution.

Proof of Concept

This PoC shows that when user2, user3 and user4 claimed from the faucet for the 1st time they received Sepolia ETh and dailyDrips increased to 3 but when user1 claimed from the faucet again dailyDrips reset to 0

// Test shows that when user1 claimed the faucet again it reset the dailyDrips
function testdailydripreset() public {
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
// Setting the block.timestamp for 3 days after
vm.warp(block.timestamp + raiseBoxFaucet.CLAIM_COOLDOWN());
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user3);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user4);
raiseBoxFaucet.claimFaucetTokens();
console.log("Drip before the reclaim by user 1st",raiseBoxFaucet.dailyDrips());
assertEq(raiseBoxFaucet.dailyDrips(), 150000000000000000);
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
console.log("Drip after the reclaim by user 1st",raiseBoxFaucet.dailyDrips());
assertEq(raiseBoxFaucet.dailyDrips(), 0);
}
// Console Output
Ran 1 test for test/RaiseBoxFaucet.t.sol:TestRaiseBoxFaucet
[PASS] testdailydripreset() (gas: 591487)
Logs:
Drip before the reclaim by user 1st 150000000000000000
Drip after the reclaim by user 1st 0

Recommended Mitigation

Remove the else part in the if-else block which checks if a user has claimed for the first time

Remove the else part in the if-else block which checks if a user has claimed for the first time
- else {dailyDrips = 0;}
Updates

Lead Judging Commences

inallhonesty Lead Judge 1 day ago
Submission Judgement Published
Validated
Assigned finding tags:

dailyDrips Reset Bug

Support

FAQs

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