The Snow
contract's collectFee()
function uses a low-level .call{value: ...}("")
to forward all ETH held by the contract to the s_collector
address. While it uses require(collected, ...)
to check the return status of the call, this does not guarantee that the transfer was safe or that the funds are not stuck.
In a scenario where the s_collector
is a contract with either no receive()
/fallback()
function or with logic that reverts or consumes too much gas (e.g., reentrancy), the ETH transfer will fail. Although the function correctly reverts on failure, repeated calls will continue to fail, potentially locking all ETH in the contract permanently if a valid collector address is never restored.
The collectFee()
function is expected to send all held WETH and ETH from the contract to the s_collector
address safely and atomically.
If the s_collector
is non-payable, reverts during receive, or is a contract with fallback/receive functions consuming excessive gas or performing reentrancy, the call will fail. The function will revert, but the ETH remains stuck and inaccessible.
This will occur when a collector contract lacks a receive()
or fallback()
function or includes logic that makes it non-payable or gas-intensive.
If a collector contract is upgraded or replaced with a hostile or broken address, fee collection can permanently fail.
Loss of access to ETH funds in the Snow
contract.
Repeated failures to collect fees can render the collectFee()
function useless and lead to operational degradation of the system.
Avoid using .call{value: ...}("")
directly for ETH transfers without explicit gas forwarding or security checks.
Instead:
Use a pull pattern where the collector withdraws ETH when desired.
Or leverage OpenZeppelin’s Address.sendValue()
which reverts if the transfer fails and mitigates gas stipend issues.
Consider implementing a SafeTransferLib
-style ETH transfer using call
, with checks for contract reentrancy or non-payable recipients.
Example using OZ's safer pattern:
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.