LikeRegistry holds user ETH via likeUser() calls, which (once the balance-credit bug is fixed) write incoming ETH to userBalances[msg.sender]. The owner can withdraw accumulated protocol fees via withdrawFees(), which draws from totalFees. The contract balance should at all times equal the sum of all userBalances plus totalFees.
The contract declares a bare receive() fallback:
This allows any address to send arbitrary ETH directly to LikeRegistry without triggering any accounting. ETH sent this way is not written to userBalances or totalFees. The withdrawFees() function only withdraws from totalFees — it has no visibility into the untracked balance surplus. There is no rescueETH(), no sweep(), and no other mechanism to recover these funds.
The result is a permanently growing gap between address(this).balance and the sum of all accounted balances — ETH that sits in the contract and is inaccessible to anyone.
Likelihood:
Direct ETH sends to contract addresses happen regularly: users testing the contract, wallet software that sends ETH to the last interacted address, accidental transfers from exchanges, and protocol integrations that push ETH before calling a function.
The bare receive() means all of these silently succeed instead of reverting, providing no feedback that the ETH is lost.
Impact:
Any ETH sent via receive() is permanently locked with no recovery mechanism for either the sender or the contract owner.
The discrepancy between address(this).balance and accounted balances can confuse off-chain monitoring tools and accounting dashboards, masking the actual health of the protocol's ETH reserves.
Either remove the bare receive() (to revert accidental sends) or add a rescueETH() owner function that recovers the unaccounted surplus:
Option A — Remove receive() (preferred if direct ETH sends are not a use case):
Option B — Add rescueETH() to recover untracked surplus:
For Option B, totalUserBalances must be tracked as a running sum incremented in likeUser() and decremented in matchRewards().
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.