DatingDapp

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

[H-1] Inaccurate Fee Calculation in LikeRegistry Contract

Summary

The LikeRegistry contract had a vulnerability in its fee calculation logic, where the total fees collected were not accurately updated based on the fixed fee percentage.

Vulnerability Details

The contract's matchRewards function is responsible for calculating and deducting a fixed percentage fee from the total rewards distributed to matched users. However, due to incorrect calculations or state updates, the totalFees variable were not accurately reflect the cumulative fees collected over time.

If the fixed fee percentage is set at 10%, and two users are matched with a total reward of 2 ETH, the expected fee should be 0.2 ETH. If the contract fails to add this amount to totalFees, it results in an underreported fee collection

Below is the POC:

I run the below POC by forge test --match-test testFeeCalculationInvariant -vvv

and this was the result

function testFeeCalculationInvariant() public {
uint256 initialTotalFees = likeRegistry.totalFees();
console.log("Initial Total Fees: ", initialTotalFees);
// Simulate user1 liking user2
vm.prank(user1);
likeRegistry.likeUser{value: 1 ether}(user2);
console.log("user1 liked user2");
// Simulate user2 liking user1
vm.prank(user2);
likeRegistry.likeUser{value: 1 ether}(user1);
console.log("user2 liked user1");
uint256 expectedFees = (2 ether * 10) / 100; // 0.2 ETH
uint256 newTotalFees = likeRegistry.totalFees();
console.log(" Expected Fees: ", expectedFees);
console.log(" New Total Fees: ", newTotalFees);
assertEq(newTotalFees, initialTotalFees + expectedFees, "Total fees should be correctly updated");
}

Impact

  • If the user balances are not updated then there would be 0 rewards send to multisig wallet.

Tools Used

Foundry invariant testing

Recommendations

Update the user balances when user calls the function likeUser. After incorporating this line I ran the POC again and this was the result

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; // Add this line
likes[msg.sender][liked] = true;
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);
}
}
Updates

Appeal created

n0kto Lead Judge 6 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.