DatingDapp

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

Missing Balance Recording in Like Function Results in Permanent Loss of User Funds

Summary

Vulnerability Details

The likeUser function fails to record user deposits when processing likes, leading to permanent loss of user funds. When users deposit ETH (minimum 1 ether) to like another address, the contract accepts the payment but fails to update the user's balance in the userBalances mapping.

Here is the vulnerable code:

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;
emit Liked(msg.sender, liked);
// @audit-issue- Critical: No balance recording.
// 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);
}
}

Impact

Users permanently lose their deposited funds.

Tools Used

Manual Review

Proof of concept

Configure the likeRegistry into the testSoulboundProfileNFT.t.sol, so as to enable likeRegistry contract .

  • import LikeRegistry.sol

import "../src/LikeRegistry.sol";
  • Set up the LikeRegistry contract for easy interaction.

  • Add the below foundry test to test file.

function testUserBalanceNotUpdated() public {
vm.deal(user, 10 ether);
vm.prank(user);
soulboundNFT.mintProfile("Alice", 25, "ipfs://profileImage");
uint256 userInitialBalance = user.balance;
vm.prank(user2);
soulboundNFT.mintProfile("Bob", 20, "ipfs://profileImage2");
vm.prank(user);
likeRegistry.likeUser{value: 1 ether}(user2);
assertEq(likeRegistry.userBalances(user), 0); // Balance remains zero despite deposit
}

Recommendations

To fix this issue consider the below update.

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;
emit Liked(msg.sender, liked);
+ userBalances[msg.sender] = msg.value;
// 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);
}
}
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.