Normal behavior:
When a user calls claimFaucetTokens(), the contract should record that the user has made a claim (lastClaimTime), increment the daily claim counter, and then send the faucet tokens and (for first-time claimers) a small Sepolia ETH drip.
Vulnerability:
The contract makes an external call (sending Sepolia ETH to the user faucetClaimer.call{value: ...}("")) before updating critical state variables such as lastClaimTime and dailyClaimCount.
A malicious contract can use its fallback or receive function to re-enter claimFaucetTokens() during the same transaction — allowing multiple token transfers before the cooldown or claim limits are enforced.
Additionally, storing faucetClaimer as a state variable instead of using a local variable further increases reentrancy surface and potential state confusion.
Likelihood:
The issue will occur whenever a malicious smart contract claims from the faucet for the first time and receives Sepolia ETH — its fallback can re-enter claimFaucetTokens() before state is updated.
Any time the faucet has sufficient ETH balance to drip, a reentrancy can be triggered to drain tokens and bypass the cooldown and daily claim limits.
Impact:
An attacker can drain all faucet tokens by repeatedly re-entering the function before the state variables are updated.
An attacker can drain all faucet tokens by repeatedly re-entering the function before the state variables are updated.
MaliciousClaimer receives multiple faucet token transfers within a single transaction, bypassing the 3-day cooldown and daily limits.
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.
The contest is complete and the rewards are being distributed.