DatingDapp

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

Excess ETH Sent in likeUser Not Refunded

Root + Impact

Description

  • The `likeUser()` function requires users to send at least 1 ETH (`require(msg.value >= 1 ether)`), but it does not refund any excess ETH if users send more than 1 ETH. The excess ETH remains in the contract and is effectively lost to the user, as there's no mechanism to recover it.

    ```solidity

    function likeUser(address liked) external payable {

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

    // @> If msg.value > 1 ether, excess is not refunded

    // ...

    }

    ```

    ### Root Cause

    The function only checks the minimum value but doesn't handle cases where more than 1 ETH is sent. The excess ETH is included in the contract balance but not tracked or refunded.


Risk

Likelihood:

  • * Users may accidentally send more than 1 ETH due to UI errors or miscalculation

    * Users may intentionally send more thinking it provides additional benefits

    * This will occur whenever msg.value > 1 ether

Impact:

  • * Users lose excess ETH permanently

    * Poor user experience and potential financial loss

    * Excess ETH accumulates in the contract with no way for users to recover it

    * If excess ETH is significant, it could be considered a form of fund loss

Proof of Concept

```solidity
// User accidentally sends 2 ETH instead of 1 ETH
likeRegistry.likeUser{value: 2 ether}(userB);
// Only 1 ETH should be used, but 2 ETH is sent
// 1 ETH is lost to the user
// If balance tracking worked, userBalances would be incremented by 2 ETH instead of 1 ETH
```

Recommended Mitigation

Option 1: Refund excess ETH
```diff
function likeUser(address liked) external payable {
require(msg.value >= 1 ether, "Must send at least 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");
+ uint256 excess = msg.value - 1 ether;
userBalances[msg.sender] += 1 ether;
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 (excess > 0) {
+ (bool success,) = payable(msg.sender).call{value: excess}("");
+ require(success, "Refund failed");
+ }
}
```
Option 2: Require exact amount
```diff
function likeUser(address liked) external payable {
- 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 16 days 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!