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:
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);
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);
}
}