Raisebox Faucet

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

[H-01] Daily ETH drip cap can be broken

Daily ETH drip cap can be broken

Description

  • Normal behaviour: There needs to be some kind of counter/cap that is essential for fair faucet and token distribution. dailyDripsshould keep track of the cumulative amount of Sepolia ETH that was distributed in a 24h window until cap dailySepEthCap.

    A user who has not claimed any seplia eth yet, because she is new to the faucet hasClaimedEth[faucetClaimer] == false or Sepolia Eth drips was paused sepEthDripsPaused == true, will reset the dailyDrips counter on the next day.


  • Issue: An attacker can reset the daily Sepolia Eth distribution amount by using an account that has already received the initial Sepolia ETH hasClaimedEth[faucetClaimer] == true or when paused sepEthDripsPaused == true . By creating of multiple of accounts the contract can be drained of the Sepolia Eth amount, or any other native token/mainnet ETH when deployed on other chains.

// drip sepolia eth to first time claimers if supply hasn't ran out or sepolia drip not paused**
// still checks
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
...
} else {
@> dailyDrips = 0;
}

Risk

Likelihood (high):

  • The glitch occurs every time if a claimer returns for 2nd or when a user claims but ETH drips paused

Impact:

  • Critical functionality bypass, ETH drips cap circumvented

  • ETH reserves are drained

Proof of Concept

dailyDrips can be reset.

function test_claimFaucetTokens_DailyEthDripCapCanBeBroken() public {
// Wait 3 days after deployment
vm.warp(block.timestamp + 3 days);
vm.roll(block.number + 1);
// Initial claim by user
vm.prank(user);
raiseBoxFaucet.claimFaucetTokens();
// Fast forward 3 days (wait for cooldown for user)
vm.warp(block.timestamp + raiseBoxFaucet.CLAIM_COOLDOWN() + 1 days);
vm.roll(block.number + 1);
// Other users claim faucet tokens, increasing dailyDrips
vm.prank(alice);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(bob);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(charlie);
raiseBoxFaucet.claimFaucetTokens();
// 2nd claim by user. This resets dailyDrips to 0 again
vm.prank(user);
raiseBoxFaucet.claimFaucetTokens();
// dailyDrips is now 0
assertEq(raiseBoxFaucet.dailyDrips(), 0);
}

Recommended Mitigation

Remove the erroneous else block that resets dailyDrips = 0.

// drip sepolia eth to first time claimers if supply hasn't ran out or sepolia drip not paused**
// still checks
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
...
+ }
- } else {
- dailyDrips = 0;
- }
Updates

Lead Judging Commences

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