Raisebox Faucet

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

Incorrect dailyDrips reset allows bypassing daily cap

Author Revealed upon completion

dailyDrips is wrongly reset , letting new users bypass the daily cap and claim Ether.

Description

  • In RaiseBoxFaucet::claimFaucetTokens, when a user who has already claimed ETH or when sepEthDripsPaused is true, calling the function resets the dayDrips variable.

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;
}
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 Incorrect state reset
@> dailyDrips = 0;
}
...
}

Risk

  • Likelihood: High

  • Impact: This allows unlimited daily Ether drips to new users beyond the configured cap.

Proof of Concept

  • Run the following test.

  • We set 1 ETH dripped per first-time claim and 2 ETH distributed per day. After user2 and user3 claimed, the daily limit was reached. But user4 will get ETH, because user1 called the function.

// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.30;
import {Test, console} from "../lib/lib/forge-std/src/Test.sol";
import {RaiseBoxFaucet} from "../src/RaiseBoxFaucet.sol";
contract Audit_Test is Test {
function test_dripETH() public{
RaiseBoxFaucet raiseBoxFaucet;
raiseBoxFaucet = new RaiseBoxFaucet(
"raiseboxtoken",
"RB",
1000 * 10 ** 18,
1 ether,
2 ether // 1 ether for dailySepEthCap
);
vm.deal(address(raiseBoxFaucet), 4 ether);
address user1 = makeAddr("1");
address user2 = makeAddr("2");
address user3 = makeAddr("3");
address user4 = makeAddr("4");
vm.warp(3 days);
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
vm.warp(block.timestamp + 3 days);
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user3);
raiseBoxFaucet.claimFaucetTokens();
// ↑ Reach the daily cap of 2 ether after user2 and user3 claim
vm.prank(user1);
//@audit This will reset the dailyDrips to 0
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user4);
raiseBoxFaucet.claimFaucetTokens();
assert(address(user1).balance == 1 ether);
assert(address(user2).balance == 1 ether);
assert(address(user3).balance == 1 ether);
assert(address(user4).balance == 1 ether);
}
}

Recommended Mitigation

  • dailyDrips is already reset elsewhere. Remove the else block and dailyDrips = 0;.

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;
}
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 {
- dailyDrips = 0;
}
...
}
Updates

Lead Judging Commences

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