The claimFaucetTokens function in the RaiseBoxFaucet contract contains a logic error in its Sepolia ETH drip mechanism. In the else block of the ETH drip logic, the dailyDrips state variable, which tracks the total Sepolia ETH distributed per day, is unconditionally reset to zero (dailyDrips = 0) when a claimant is either not a first-time claimer (!hasClaimedEth[faucetClaimer]) or Sepolia ETH drips are paused (sepEthDripsPaused). This reset occurs every time a non-first-time claimer executes the function, effectively bypassing the dailySepEthCap limit on the same day. This allows subsequent first-time claimers to claim more Sepolia ETH than intended on the same day, potentially draining the contract's ETH balance beyond the daily cap.
Invariant Violation: The contract intends to drip exactly 0.005 sepolia eth to first users (Sepolia eth Drip Invariant). The unintended reset of dailyDrips allows attackers to bypass the daily Sepolia ETH distribution limit (dailySepEthCap) by using non-first-time claimers to reset the tracker after initial drips on a new day. This leads to excessive ETH claims, breaking this invariant and undermining fair distribution.
High
The unintended reset of dailyDrips allows attackers to bypass the daily Sepolia ETH distribution limit (dailySepEthCap) by using non-first-time claimers to reset the tracker after initial drips on a new day. This leads to excessive ETH claims. In a testnet faucet context, this could drain the contract's Sepolia ETH reserves faster than intended, disrupting service for legitimate users. In a mainnet scenario, this would result in significant financial loss.
Excessive ETH Distribution: Attackers can use non-first-time claimers to reset dailyDrips multiple times on the same day, allowing additional first-time claims beyond dailySepEthCap.
Faucet Depletion: Rapid depletion of the contract’s ETH balance on a given day, preventing legitimate first-time claimers from receiving their Sepolia ETH drip after the cap is artificially bypassed.
Loss of Trust: Undermines the protocol’s fairness and reliability, as the daily cap is not enforced properly.
Manual code review
Foundry (for Proof of Concept testing)
Remove Unconditional Reset: Remove the dailyDrips = 0 statement from the else block to prevent unintended resets of the daily ETH cap tracker.
Consistent Reset Logic: Ensure dailyDrips is only reset in the if (currentDay > lastDripDay) block, which aligns with the daily reset logic for ETH drips.
Add Explicit Reset Check: If the reset is intentional for specific cases, add documentation and a conditional check to ensure it only occurs when necessary (e.g., explicitly reset only after a day has passed).
Modified Code Example:
The following Foundry test demonstrates the bug by showing how a non-first-time claimer can reset dailyDrips on a new day, allowing excessive Sepolia ETH claims beyond the daily cap on that day.
Explanation of PoC:
The test deploys the RaiseBoxFaucet contract with a dailySepEthCap of 0.005 ETH and sepEthAmountToDrip of 0.005 ETH.
Warps time to a realistic timestamp (October 14, 2025) to avoid initial cooldown revert issues.
On Day 1, claimer1 claims 0.005 ETH (first-time).
Warps forward 3 days to Day 4.
On Day 4, claimer2 claims 0.005 ETH (first-time, dailyDrips updated to 0.005).
claimer1 claims again (non-first-time), triggering the else block and resetting dailyDrips to 0.
claimer3 claims 0.005 ETH (first-time), which succeeds despite the cap because dailyDrips was reset, resulting in 0.01 ETH dripped on Day 4 (exceeding the 0.005 ETH cap).
The test verifies the contract’s ETH balance decreases by more than the daily cap on Day 4, confirming the bug.
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.