The withdrawFees()
function in LikeRegistry.sol
transfers ETH from the contract to the owner without verifying the recipient's validity. If owner() returns an unintended or compromised address (e.g., address(0), an external contract, or an address controlled by an attacker), the funds may be lost or misused. Implementing additional recipient validation is recommended to ensure the transfer behaves as expected.
Code Snippet:
Why is this an issue?
No validation on owner()
If owner()
returns an unintended or uninitialized address (e.g., address(0)), ETH could be sent to a burn address and permanently lost.
If owner()
is set to a contract that does not accept ETH, the transfer will always fail.
No reentrancy protection
If the owner()
is a contract with malicious behavior, it could reenter the contract and drain additional funds before state changes are finalized.
PoC:
Consider a scenario where the owner()
address is accidentally set to address(0)
.
The contract accumulates fees:
The owner is unintentionally set to address(0).
Calling withdrawFees()
sends 10 ETH to address(0), permanently locking the funds.
High Severity: This vulnerability can cause an irreversible loss of funds if the recipient is invalid.
Reentrancy Risk: If owner() is a malicious contract, it could execute reentrant attacks.
Failed Transfers: If owner() is a contract without a payable fallback function, ETH transfers will fail, locking funds in the contract.
Manual Review
Aderyn
Add recipient validation and reentrancy protection using nonReentrant from OpenZeppelin’s ReentrancyGuard:
Instead of call{value: ...}(""),
which can lead to reentrancy risks, use .send()
or .transfer()
for additional safety:
or
However, transfer()
and send()
limit gas to 2300, which might cause issues if owner() is a smart contract.
Use a Multi-Signature Wallet for Withdrawals.
Instead of allowing a single owner to withdraw funds, use a multisig wallet (e.g., Gnosis Safe) for enhanced security.
Emit an Event for Transparency
Add an event to log withdrawals:
Emit the event inside withdrawFees().
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
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.