DatingDapp

AI First Flight #6
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: low
Invalid

[M-03] Excess ETH sent with `likeUser()` is not refunded due to `>=` check instead of `==`

Description

likeUser() uses require(msg.value >= 1 ether) instead of ==, accepting any amount above 1 ETH without refunding the excess. The error message actively encourages overpayment.

Vulnerability Details

// src/LikeRegistry.sol, line 32
require(msg.value >= 1 ether, "Must send at least 1 ETH");
// @> accepts 10 ETH, 100 ETH — excess never refunded

The contract has no refund mechanism. Any ETH above 1 ETH is absorbed into the contract balance and either locked permanently (due to H-01) or distributed unevenly through matchRewards() if H-01 is fixed. The error message says "Must send at least 1 ETH," which actively invites users to send more than required. Users interacting via a custom frontend, script, or directly through Etherscan can easily send more than 1 ETH.

Risk

Likelihood:

  • Wallet UIs that auto-suggest gas amounts or users who mistype the value trigger this. The error message's wording ("at least") actively encourages overpayment.

Impact:

  • Excess ETH is permanently lost to the user. With H-01 present, it is locked forever. With H-01 fixed, it inflates that user's userBalances and gets distributed to whichever match triggers first, benefiting the wrong counterparty.

PoC

The test shows Alice sending 5 ETH instead of the required 1 ETH. The contract keeps all 5 ETH with no refund of the 4 ETH excess. Alice's balance drops by the full 5 ETH.

function testExcessETHNotRefunded() public {
uint256 aliceBalanceBefore = alice.balance;
vm.prank(alice);
likeRegistry.likeUser{value: 5 ether}(bob);
// Contract keeps ALL 5 ETH, not just 1
assertEq(address(likeRegistry).balance, 5 ether);
// Alice lost 5 ETH instead of 1 — 4 ETH overpayment with no refund
assertEq(alice.balance, aliceBalanceBefore - 5 ether);
}

Recommendations

Change the >= to == so the function only accepts exactly 1 ETH. This prevents accidental overpayment and makes the expected value unambiguous. Users who send the wrong amount get a clear revert instead of silently losing funds.

- require(msg.value >= 1 ether, "Must send at least 1 ETH");
+ require(msg.value == 1 ether, "Must send exactly 1 ETH");
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 16 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!