The contract exposes a payable receive() function allowing arbitrary ETH transfers directly to the contract.
However, the protocol only allows withdrawal of tracked totalFees.
ETH received outside the expected accounting flow cannot be recovered through any existing function.
Users sending ETH directly to the contract or accidentally overpaying may permanently lose funds.
Likelihood:
Users commonly send ETH directly to contracts accidentally through wallets or block explorers.
Any ETH transferred outside fee accounting remains untracked.
Impact:
ETH becomes permanently locked inside the protocol.
Users may irreversibly lose funds.
Contract balance can diverge from protocol accounting assumptions.
The following test demonstrates that arbitrary ETH can be sent directly to the contract through the receive() function without being tracked by the protocol accounting system.
First, the test funds a user account with 1 ether using vm.deal().
The user then directly transfers ETH to the LikeRegistry contract using a low-level .call{value: 1 ether}(""), which triggers the payable receive() function.
Because the receive() function accepts ETH without updating any accounting variables such as totalFees, the deposited ETH becomes untracked.
The test then verifies that:
The ETH transfer succeeds.
The contract balance increases by 1 ether.
The owner is unable to withdraw the ETH because withdrawFees() only allows withdrawal of totalFees, which remains 0.
As a result, the transferred ETH becomes permanently locked inside the contract.
The simplest mitigation is to reject arbitrary ETH transfers by reverting inside the receive() function.
This ensures that users can only send ETH through intended protocol flows where accounting and balance tracking are properly handled.
Rejecting direct ETH transfers prevents:
Accidental user fund loss.
Untracked ETH accumulation.
Divergence between actual contract balance and protocol accounting variables.
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.