DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Stuck ETH in LikeRegistry Contract

Summary

The LikeRegistry contract contains a critical issue where the userBalances mapping is never updated when users send ETH via the likeUser function. As a result, all ETH sent remains stuck in the contract without a way to withdraw or transfer it.

Affected Contract

contract LikeRegistry {
function likeUser(address liked) external payable {
require(msg.value >= 1 ether, "Must send at least 1 ETH");
...
// No update to userBalances[msg.sender] here
}
}

Impact

  • All ETH sent by users remains locked within the contract since userBalances is never updated.

  • Users cannot retrieve their ETH, resulting in a financial loss.

  • The contract does not implement a way to utilize or distribute these funds, making them permanently inaccessible.

Steps to Reproduce (Proof of Concept - PoC)

  1. Deploy the LikeRegistry and SoulboundProfileNFT contracts.

  2. Create two users (user and user2) and mint profile NFTs for them.

  3. Have user send 2 ETH when calling likeUser(user2).

  4. Check the contract balance and observe that it contains 2 ETH, while userBalances[user] remains 0.

  5. The ETH is permanently locked inside the contract.

PoC Code (Using Foundry)

function testStuckEth() public {
vm.prank(user);
soulboundNFT.mintProfile("dsa", 2, "ipfs://profileImage");
vm.prank(user2);
soulboundNFT.mintProfile("fsa", 5, "ipfs://profileImage");
vm.deal(user, 2 ether);
vm.prank(user);
likeRegistry.likeUser{value: 2 ether}(user2);
uint256 contractBalance = address(likeRegistry).balance;
assertEq(contractBalance, 2 ether, "Contract should have 2 ETH");
}

Recommended Fix

Modify the likeUser function to properly update userBalances when ETH is sent:

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");
likes[msg.sender][liked] = true;
userBalances[msg.sender] += msg.value; // Fix: Track ETH sent
emit Liked(msg.sender, liked);
if (likes[liked][msg.sender]) {
matches[msg.sender].push(liked);
matches[liked].push(msg.sender);
emit Matched(msg.sender, liked);
matchRewards(liked, msg.sender);
}
}

Severity

  • High: Funds are permanently locked with no way to retrieve them.

Conclusion

This vulnerability results in ETH being stuck in the contract, preventing users from reclaiming their funds. The recommended fix ensures that userBalances correctly tracks ETH sent, preventing the loss of funds.

Updates

Appeal created

n0kto Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_likeUser_no_userBalances_updated

Likelihood: High, always. Impact: High, loss of funds

Support

FAQs

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