Expected Behavior:
The claimFaucetTokens() function should transfer tokens and ETH safely to users in a way that prevents reentrancy.
External calls (like sending ETH) should be protected so attackers can’t repeatedly drain the faucet by reentering before state updates finish.
Actual Behavior:
The function performs an external call using faucetClaimer.call{value: sepEthAmountToDrip}("") without a reentrancy guard.
This allows a malicious contract to reenter claimFaucetTokens() within the same transaction, bypassing the cooldown and claim count logic potentially draining ETH and faucet tokens.
Root Cause:
The contract performs an unprotected external call (.call{value: ...}) before completing all state updates.
This introduces a reentrancy vector, especially since the cooldown and claim counters (lastClaimTime, dailyClaimCount) can be manipulated mid-call.
Likelihood
High: Very likely since any malicious contract can exploit .call() easily if not guarded.
Impact:
1.Attackers can reenter before state updates, claiming multiple times in one transaction.
2.ETH and faucet tokens can be drained quickly, bypassing intended claim limits.
3.Causes financial and functional failure of the faucet system.
Explanation:
The exploit reenters claimFaucetTokens() via the fallback when ETH is sent, before cooldowns and claim counts are finalized ,letting it drain multiple claims in one go.
Explanation
Adds ReentrancyGuard from OpenZeppelin.
Applies nonReentrant to ensure that no nested external calls to the same function can occur.
Prevents multiple claims within a single transaction.
Protects both ETH and token balances from reentrancy-based draining.
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.