DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

Sending ETH to the `LikeRegistry` contract causes the funds to be stuck there permanently.

Description:

The LikeRegistry contract includes a receive() function, allowing anyone to send ETH directly to the contract. However, it lacks any withdrawal mechanism or function to recover these funds. As a result, any ETH sent directly to this contract becomes irretrievably locked, effectively leading to a permanent loss of the transferred funds. This design oversight may pose significant financial loses and should be addressed to ensure proper fund management.

Impact: This vulnerability leads to permanent loss of the transferred funds.

Proof of Concept:

Import the LikeRegistry contract into SoulboundProfileNFTTest contract.

pragma solidity ^0.8.19;
import {Test, console} from "forge-std/Test.sol";
import "../src/SoulboundProfileNFT.sol";
+ import {LikeRegistry} from "../src/LikeRegistry.sol";
contract SoulboundProfileNFTTest is Test {

Place the following declaration into SoulboundProfileNFTTest contract.

contract SoulboundProfileNFTTest is Test {
SoulboundProfileNFT soulboundNFT;
+ LikeRegistry likeRegistry;
address user = address(0x123);

Place the following test into testSouldboundProfileNFT.t.sol

function test_FundsStuckInLikeRegistry() public {
address anyUser = makeAddr("sender");
vm.deal(anyUser, 1 ether);
vm.prank(anyUser);
likeRegistry = new LikeRegistry(address(soulboundNFT));
vm.expectRevert();
(bool success, ) = payable(address(likeRegistry)).call{value: 1 ether}(
""
);
require(success);
}

Recommended Mitigation: Consider adding withdraw function. Best thing to do here is allowing users to make withdraw.

  1. Add this line to the LikeRegistry::Receive function. That way we can track the balance of sender.

receive() external payable {
+ userBalances[msg.sender] += msg.value;
}
  1. Add this function to LikeRegistry.

function withdraw(uint256 _amount) external {
uint256 userBalance = userBalances[msg.sender];
// Check amount and user balance.
require(_amount > 0, "Withdraw amount must be bigger than 0.");
require(userBalance >= _amount, "Insufficient user balance.");
// Update the user balance.
balances[msg.sender] -= _amount;
// Send ETH.
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "ETH transfer failed.");
}
Updates

Appeal created

n0kto Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

invalid_receive_function

Not the best design, but if you send money accidentally, that's a user mistake. Informational.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.