Description:
The matchRewards
function fetches ETH balances from userBalances[from]
and userBalances[to]
but these balances are never updated when users send ETH via likeUser
.
Impact:
Since userBalances
is never updated, the matchRewards
function will always consider these values as zero, leading to an incorrect reward distribution. Additionally, ETH accumulates in the contract without being properly accounted for
Proof of Concept:
Created an external function to view the userBalances mapping.
function getUserBalance(address user) external view returns (uint256) {
return userBalances[user];
}
Place this in the testLikeRegistry.t.sol
file.
function testMatchedUsersBalancesUpdated() public {
deal(userA, 2 ether);
deal(userB, 2 ether);
vm.startPrank(userA);
profileNft.mintProfile("userA", 25, "ipfs://profileImage");
vm.stopPrank();
vm.startPrank(userB);
profileNft.mintProfile("userB", 25, "ipfs://profileImage");
vm.stopPrank();
vm.prank(userA);
likeRegistry.likeUser{value: 1 ether}(userB);
vm.prank(userB);
likeRegistry.likeUser{value: 1 ether}(userA);
uint256 userBalanceOfUserA = likeRegistry.getUserBalance(userA);
uint256 userBalanceOfUserB = likeRegistry.getUserBalance(userB);
console2.log("This is the user balance of UserA::", userBalanceOfUserA);
console2.log("This is th user balance of UserB::", userBalanceOfUserB);
}
These were the following logs that were outputted:
534] LikeRegistry::getUserBalance(ECRecover: [0x0000000000000000000000000000000000000001]) [staticcall]
│ └─ ← [Return] 0
├─ [534] LikeRegistry::getUserBalance(SHA-256: [0x0000000000000000000000000000000000000002]) [staticcall]
│ └─ ← [Return] 0
├─ [0] console::log("This is the user balance of UserA::", 0) [staticcall]
│ └─ ← [Stop]
├─ [0] console::log("This is th user balance of UserB::", 0) [staticcall]
│ └─ ← [Stop]
Meaning that the userBalances
is not updated this making the reward distribution system of the protocol to be null and void.
Recommended Mitigation:
The userBalances
mapping should be updated in the likeUser
function as shown below.
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");
+ userBalances[msg.sender] += msg.value;
likes[msg.sender][liked] = true;
// event emitted correctly..
emit Liked(msg.sender, liked);
// 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);
}
}