Description
In LikeRegistry
contract when one user liked other user he have to pay 1 ETH.
This happens, using LikeRegistry::likeUser
function, so when user pay to like other one, the mapping userBalances
should be updated. However when function is called, ether is send to the contract, but the variable is not updated.
Impact
The variable that is used to track user balances is not updated and this break the whole idea of the protocol.
Funds are being stollen to the smart contract.
Proof of Concepts
Create test file called LikeRegistryTest.t.sol
Place the following code :
pragma solidity 0.8.20;
import {Test, console} from "forge-std/Test.sol";
import {LikeRegistry} from "src/LikeRegistry.sol";
import {SoulboundProfileNFT} from "src/SoulboundProfileNFT.sol";
contract LikeRegistryTest is Test {
SoulboundProfileNFT profileNFT;
LikeRegistry likeRegistry;
address owner = makeAddr("owner");
address alice = makeAddr("alice");
address bob = makeAddr("bob");
address george = makeAddr("george");
string constant IPFS_PROFILE_IMAGE = "ipfs://bafybeieoydho7jz6cqberycgzowstnj6lrq6ku2ngc3u7mx22izqzk2q4y/50";
function setUp() public {
vm.startPrank(owner);
profileNFT = new SoulboundProfileNFT();
likeRegistry = new LikeRegistry(address(profileNFT));
vm.stopPrank();
vm.deal(alice, 100 ether);
vm.deal(bob, 100 ether);
vm.deal(george, 100 ether);
}
modifier createProfiles() {
vm.prank(alice);
profileNFT.mintProfile("Alice", 34, IPFS_PROFILE_IMAGE);
vm.prank(bob);
profileNFT.mintProfile("Bob", 42, IPFS_PROFILE_IMAGE);
vm.prank(george);
profileNFT.mintProfile("George", 27, IPFS_PROFILE_IMAGE);
_;
}
function testLikeUser() public createProfiles {
vm.prank(bob);
likeRegistry.likeUser{value: 1 ether}(alice);
uint256 bobBalanceInLikeRegistry = likeRegistry.userBalances(bob);
assertEq(bobBalanceInLikeRegistry, 0);
}
}
Run the command on the terminal forge test --mt testLikeUser
Recommended mitigation
Consider to update the mapping funds are being deposited to the contract.
Example:
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] += 1 ether;
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);
}
}