DatingDapp

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

Overpayment Without Refund Mechanism

Summary

The likeUser function requires a minimum payment of 1 ETH but allows users to pay more without any mechanism to return the excess to the user. The check require(msg.value >= 1 ether, "Must send at least 1 ETH"); uses >= instead of ==, which does not enforce strict equality to 1 ETH.

Vulnerability Details

Steps to Reproduce:
Deploy the LikeRegistry contract with the modified likeUser function.
As a user with address 0x123, attempt to call likeUser with more than 1 ETH:
```solidity
likeRegistry.likeUser{value: 2 ether}(address(0x456));
```
Observe that the transaction should revert due to the strict equality check.
PoC Code:
```solidity
function testOverpaymentWithStrictCheck() public {
address user = address(0x123);
address liked = address(0x456);
vm.deal(user, 3 ether);
uint256 initialBalance = user.balance;
vm.expectRevert("Must send exactly 1 ETH");
vm.prank(user);
likeRegistry.likeUser{value: 2 ether}(liked);
// Check if the transaction reverts and no ETH is taken
assertEq(user.balance, initialBalance, "User balance should remain unchanged due to revert");
}
```
Explanation:
This PoC demonstrates that with strict equality checks, the function will revert if the user attempts to pay more than 1 ETH, ensuring that only the exact amount is accepted. This prevents overpayment and the subsequent need for refunds or fund management within the contract.

Impact

Users might inadvertently or intentionally pay more than 1 ETH, leading to unnecessary funds being locked in the contract.
If there's no way to withdraw this excess, it effectively becomes a donation to the contract, potentially leading to user dissatisfaction or exploitation.

Tools Used

Manual Review and Foundry

Recommendations

Implement a strict equality check for the payment and return any excess. Modify the function as follows:
```solidity
function likeUser(address liked) external payable {
require(msg.value == 1 ether, "Must send exactly 1 ETH");
require(!likes[msg.sender][liked], "Already liked");
require(msg.sender != liked, "Cannot like yourself");
require(profileNFT.profileToToken(msg.sender) != 0, "Must have a profile NFT");
require(profileNFT.profileToToken(liked) != 0, "Liked user must have a profile NFT");
likes[msg.sender][liked] = true;
emit Liked(msg.sender, liked);
// Check if mutual like
if (likes[liked][msg.sender]) {
matches[msg.sender].push(liked);
matches[liked].push(msg.sender);
emit Matched(msg.sender, liked);
matchRewards(liked, msg.sender);
}
}
```
If you want to allow for small deviations due to rounding errors but still return excess, you could:
```solidity
uint256 excess = msg.value - 1 ether;
if (excess > 0) {
payable(msg.sender).transfer(excess); // or use call for safety
}```
Updates

Appeal created

n0kto Lead Judge 6 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.

Support

FAQs

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