Normal behavior: The contract should track how much Sepolia ETH it has dripped during the current day in dailyDrips and only allow additional drips while dailyDrips + sepEthAmountToDrip <= dailySepEthCap. The dailyDrips counter must only be reset when a new day begins (controlled by lastDripDay), so the daily cap is enforced for the whole day.
Specific issue: The function contains an else { dailyDrips = 0; } that resets the global dailyDrips counter whenever the current caller is not eligible for an ETH drip (e.g. hasClaimedEth[caller] == true or sepEthDripsPaused == true). This per-caller branch incorrectly resets a global, per-day counter and enables an attacker to obtain additional ETH drips beyond the intended daily cap by forcing the counter to zero in the middle of the day.
Likelihood:
When faucet usage progresses during the day and dailyDrips has accumulated but not yet reached dailySepEthCap, ordinary faucet activity will eventually leave the counter in a non-zero state close to the cap.
When any address that is already ineligible for ETH (because that address previously claimed ETH) submits a transaction, this else branch executes and clears the daily counter.
Impact:
The global daily cap (dailySepEthCap) can be effectively bypassed mid-day, allowing total ETH dripped during the day to exceed the configured cap. This enables attackers or cooperating participants to extract more ETH than intended from the faucet.
The faucet’s ETH balance may be depleted faster than expected, reducing availability for legitimate users and undermining trust in the faucet’s limits.
Explanation:
userA and userB each perform a first-time claim and receive 0.5 ETH each, so dailyDrips reaches 1.0 ETH, which equals the daily cap.
When userA calls again, hasClaimedEth[userA] is true, so the code takes the outer else branch and executes dailyDrips = 0.
The attacker can then call claimFaucetTokens() and receive another 0.5 ETH drip, despite the daily cap having been reached earlier. The cumulative dripped ETH (1.5 ETH) exceeds dailySepEthCap (1 ETH).
This demonstrates that resetting dailyDrips in the else branch permits draining more ETH than the daily cap allows.
Short explanation: dailyDrips must be reset only when the day changes (i.e., when currentDay > lastDripDay) — not in any per-caller else path. Remove the else { dailyDrips = 0; } block and rely solely on the day-based reset.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.