DatingDapp

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

Lack of refund or withdraw functionality leads to inaccessible funds in the contract

Details

Funds sent to the contract are inaccessible and cannot be withdrawn by the users or the owner. The only way users get access to the funds is through the wallet created after a match. This wallet is never created if the user's balance (received from likes) is 0, and LikeRegistry::userBalances is never updated to a non-zero value in the LikeRegistry::likeUser function. The fees to be withdrawn by the owner are a percentage of the balance of the matched users. Any percentage of (0 + 0) is 0. The owner cannot withdraw any funds. Even if the LikeRegistry::userBalances is updated, there are countless scenarios that could lead to locked funds in the contract. These include inactive users, users not receiving any matches, burnt or blocked profiles etc. Even with a functional balance tracker, the lack of a refund functionality would lead to inaccessible funds in the contract.
Note: LikeRegistry::userBalances bug has been reported as a separate issue. Fixing it does not remove the requirement for refund functionality in the contract.

Impact

All funds sent to the contract are currently irretrievable due to a lack of balance tracking and updating. Even with that fixed, there is a high likelihood of locked funds due to lack of a refund function.

Proof of concept:

This test proves that funds sent to the contract are not tracked as user balances. These end up locked in the contract and cannot be refunded:

function testUserBalanceUpdate() public {
vm.deal(user, 5 ether);
uint256 balanceBefore = likeRegistry.userBalances(user2);
console.log("user balance before liking user2:", user.balance);
vm.prank(user);
likeRegistry.likeUser{value: 1 ether}(user2);
uint256 balanceAfter = likeRegistry.userBalances(user2);
console.log("user balance after liking user2:", user.balance);
assertEq(balanceBefore, balanceAfter, "userBalances are never updated");
console.log(address(likeRegistry).balance); // 1 ETH which is now inaccessible.
}

Tools Used

VSCode, Foundry

Recommendations

Update user balances and keep track of senders in case the profile goes inactive and the funds in it need to be refunded. Add a function to refund any locked funds back to the senders. Another approach would be to create an emergency withdraw function for the owner, but this could be misused and is not recommended.

Updates

Appeal created

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

invalid_no_withdrawing_function_and_like_all_used

Money collected will be sent to the MultisigWallet during the first match. Emergency withdraw could lead to a frontrun before a match. "If the like is mutual, all their previous like payments (minus a 10% fee) are pooled into a shared multisig wallet" Design choice

Support

FAQs

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