DatingDapp

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

`LikeRegistry::userBalances` never updates its value.

Description: LikeRegistry::userBalances never updates its value after user liked another profile. That results in totalRewards and totalFees always being 0.

Impact: After user call LikeRegistry::likeUser, userBalances never updates. Therefore, when the funds are transferred to MultiSigWallet, totalFees will always be 0. The deposited funds will be permanently locked in the smart contract and cannot be withdrawn.

Proof of Concept:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "forge-std/Test.sol";
import "../src/SoulboundProfileNFT.sol";
import "../src/LikeRegistry.sol";
contract LikeRegistryTest is Test {
SoulboundProfileNFT soulboundNFT;
LikeRegistry likeRegistry;
address user = address(0x123);
address user2 = address(0x456);
address user3 = address(0x789);
address owner = address(this); // Test contract acts as the owner
uint256 public constant DEFAULT_DEPOSIT_VALUE = 1 ether;
function setUp() public {
soulboundNFT = new SoulboundProfileNFT();
likeRegistry = new LikeRegistry(address(soulboundNFT));
vm.deal(user, 2 ether);
vm.deal(user2, 2 ether);
vm.deal(user3, 2 ether);
}
modifier mintProfile() {
vm.prank(user);
soulboundNFT.mintProfile("Alice", 25, "ipfs://profileImage");
vm.prank(user2);
soulboundNFT.mintProfile("Bob", 30, "ipfs://profileImage");
vm.prank(user3);
soulboundNFT.mintProfile("Anna", 20, "ipfs://profileImage");
_;
}
function testUserBalancesNeverUpdate() public mintProfile {
vm.prank(user);
likeRegistry.likeUser{value: DEFAULT_DEPOSIT_VALUE}(user2);
uint256 userBalance = likeRegistry.userBalances(user);
assertEq(userBalance, DEFAULT_DEPOSIT_VALUE, "User balance should greater than 0");
}
}

Recommended Mitigation: After the user likes a profile, we will update the value of LikeRegistry::userBalances

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;
emit Liked(msg.sender, liked);
// Check if mutual like
if (likes[liked][msg.sender]) { // matched
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.