DatingDapp

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

ETH Not Tracked in userBalances (Improper Accounting of Funds)

Description:
In the likeUser function found in the LikeRegistry, users must send at least 1 ETH when liking another user. However, the contract does not track this ETH in userBalances[msg.sender]. This means that when a match occurs, the reward distribution logic in matchRewards will not properly allocate funds, leading to potential loss or mismanagement of ETH.

Impact:

  • Users' ETH contributions are not recorded, leading to incorrect reward calculations when a match occurs.

  • When matchRewards is executed, userBalances[from] and userBalances[to] are both zero, meaning totalRewards will also be zero. Consequently, the MultiSig wallet will receive no funds, and users will not receive their match rewards.

  • The contract effectively collects ETH from users without any proper way to refund or use it as intended.

**Proof of Code: **

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "forge-std/Test.sol";
import "../src/LikeRegistry.sol";
import "../src/SoulboundProfileNFT.sol";
import "src/MultiSig.sol";
contract LikeRegistryTest is Test {
LikeRegistry public likeRegistry;
SoulboundProfileNFT public profileNFT;
address alice = address(0x1);
address bob = address(0x2);
address carol = address(0x3);
address charlie = address(0x4);
function setUp() public {
// Deploy ProfileNFT first
profileNFT = new SoulboundProfileNFT();
// Deploy LikeRegistry with ProfileNFT address
likeRegistry = new LikeRegistry(address(profileNFT));
// Mint profile NFTs for test users
vm.startPrank(alice);
profileNFT.mintProfile("Alice", 25, "ipfs://alice");
vm.stopPrank();
vm.startPrank(bob);
profileNFT.mintProfile("Bob", 28, "ipfs://bob");
vm.stopPrank();
vm.startPrank(carol);
profileNFT.mintProfile("Carol", 24, "ipfs://carol");
vm.stopPrank();
// Fund test accounts
vm.deal(alice, 10 ether);
vm.deal(bob, 10 ether);
vm.deal(carol, 10 ether);
}
function testETHNotTrackedInUserBalances() public {
// Alice likes Bob with 1 ETH
vm.startPrank(alice);
likeRegistry.likeUser{value: 1 ether}(bob);
vm.stopPrank();
// Check that userBalances mapping wasn't updated
assertEq(likeRegistry.userBalances(alice), 0, "User balance should be 0");
// Verify ETH is stuck in contract
assertEq(address(likeRegistry).balance, 1 ether, "Contract should hold 1 ETH");
}

Proof of Concept:

User A calls likeUser(userB) and sends 1 ETH.

  1. The contract does not update userBalances[userA].

  2. User B later calls likeUser(userA), creating a match.

  3. matchRewards is triggered, but since userBalances[userA] and userBalances[userB] are zero, no rewards are sent to the MultiSig wallet.

  4. The ETH remains in the contract, and users receive nothing.

Recommended Mitigation:


Modify the likeUser function to properly track ETH contributions by adding:

userBalances[msg.sender] += msg.value;
Updates

Appeal created

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