Technical Root Cause
The collectFee() function violates the fundamental Checks-Effects-Interactions pattern. It performs external calls that transfer value (ETH and WETH) before updating any internal state variables.
Why this is broken:
The function does not update any state variable (e.g., a collected flag, balance tracking, or a nonce) before making the external calls.
The contract sends ETH/WETH to s_collector, but does not mark the collection as completed or lock the function.
Because the contract's state is unchanged, an attacker can repeatedly re-enter the collectFee() function before the first execution finishes, draining the entire balance.
Impact:
| Impact | Description |
|---|---|
| Financial Loss | Total loss of all ETH and WETH held in the contract balance. |
| Irreversible | Blockchain transactions are final; drained funds cannot be recovered. |
| No Traceability | The attack is performed in a single transaction; standard monitoring may not flag it in time. |
| Affected Assets | All native ETH and any WETH tokens stored in the contract. |
An attacker can deploy a malicious contract (let's call it Attacker) that acts as the s_collector.
Step-by-step Exploit:
The attacker ensures their Attacker contract is set as the s_collector (if they have privileges) or finds a way to call collectFee().
The attacker calls collectFee() from their Attacker contract.
The Snow contract executes Line 103 or Line 105 and sends ETH/WETH to the Attacker contract.
Upon receiving the funds (via the receive() or fallback() function), the Attacker contract synchronously calls collectFee() again before the first invocation finishes.
Since the Snow contract's state has not changed (no flag set, no balance deduction tracked), the contract mistakenly thinks the full balance is still available to send.
The Snow contract sends the funds again.
The attacker repeats steps 3–6 in a loop, draining the contract balance completely in a single transaction.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.