DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

Lack of Recovery Mechanism for Accidental ETH Transfers to LikeRegistry Contract

Summary

The LikeRegistry contract is designed to facilitate user interactions—such as liking a profile and matching users—by accepting ETH payments through its likeUser function. However, the contract also includes a generic receive() function that allows it to accept ETH from any source. In the absence of a mechanism for users to recover funds mistakenly sent (either through direct transfers, transaction failures, or other errors), these ETH become permanently locked in the contract. This situation can lead to user loss of funds and may damage user trust in the platform.

Vulnerability Details

The LikeRegistry contract accepts ETH via its receive() function:

/// @notice Allows the contract to receive ETH
receive() external payable {}

The intended mechanism for sending ETH is via the likeUser function:

function likeUser(address liked) external payable {
require(msg.value >= 1 ether, "Must send at least 1 ETH");
// ... additional logic for liking a profile ...
}

If a user accidentally sends ETH to the contract—whether by a direct transfer, through a failed likeUser call (e.g., if a require condition fails), or due to a smart contract interaction mistake, there is currently no function for the user to withdraw these funds. As a result, the funds remain permanently locked in the contract.

Impact

Let's examine a real-world scenario:

Results of failed transaction:

  • ETH is transferred to contract

  • Like is not registered

  • No way to recover funds

  • User loses access to their ETH permanently

  • ETH is transferred to contract

  • Like is not registered

  • No way to recover funds

  • User loses access to their ETH permanently

Impact

Accidental Overpayment or Direct Transfer:

  • A user might mistakenly send more than the required 1 ETH when calling likeUser, or send ETH directly to the contract address.

Resulting Consequences:

  • The accidentally sent ETH is trapped in the contract because there is no recovery mechanism.

  • Users are unable to retrieve these funds, resulting in a permanent loss.

Tools Used

Manual Review

Recommendations

Implement a recovery mechanism that allows users to withdraw any ETH that was sent accidentally. One possible solution is to track accidental deposits and provide a withdrawal function. For example:

contract LikeRegistry is Ownable {
// Mapping to track accidental ETH deposits for each user
mapping(address => uint256) public accidentalTransfers;
/// @notice Modified receive function to track accidental transfers
receive() external payable {
accidentalTransfers[msg.sender] += msg.value;
}
/// @notice Allows users to withdraw accidentally sent funds
function withdrawAccidentalTransfer() external {
uint256 amount = accidentalTransfers[msg.sender];
require(amount > 0, "No funds to withdraw");
accidentalTransfers[msg.sender] = 0;
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success, "Withdrawal failed");
emit AccidentalTransferWithdrawn(msg.sender, amount);
}
event AccidentalTransferWithdrawn(address indexed user, uint256 amount);
// ... rest of the contract code ...
}
Updates

Appeal created

n0kto Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Users mistake, only impacting themselves.

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

invalid_receive_function

Not the best design, but if you send money accidentally, that's a user mistake. Informational.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.