Description
The likeUser
function requires users to send at least 1 ETH when liking another user. However, the contract does not update userBalances[msg.sender]
with the received funds, causing an issue where:
Users' payments are not tracked, meaning they are effectively lost within the contract.
The matchRewards function relies on userBalances to calculate rewards, but since the balance is never incremented, users will not receive their rightful rewards upon a match.
likeUser Function:
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);
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
Loss of funds: Users send ETH, but their balances are never updated, meaning they can never claim or use it later.
Incorrect reward distribution: The reward logic in matchRewards relies on userBalance
Proof of Concept
Add the following to the testSoulboundProfileNFT
test file.
function testIncreassesBalance() public {
likeRegistry = new LikeRegistry(address(soulboundNFT));
address alice = makeAddr("alice");
address pablo = makeAddr("pablo");
vm.prank(alice);
soulboundNFT.mintProfile("Alice", 25, "ipfs://profileImage");
vm.prank(pablo);
soulboundNFT.mintProfile("Pablo", 25, "ipfs://profileImage1");
hoax(makeAddr("pablo"), 1 ether);
console.log("Pablo balance: ", pablo.balance);
likeRegistry.likeUser{value: 1 ether}(alice);
console.log("Pablo balance: ", likeRegistry.userBalances(pablo));
assertEq(likeRegistry.userBalances(pablo), 0);
}
Tools Used
Manual
Recommendations
Update userBalances[msg.sender]
inside likeUser
function when ETH is received.
Add the following line in likeUser:
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 N FT");
+ userBalances[msg.sender] += msg.value;
likes[msg.sender][liked] = true;
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);
}
}