DatingDapp

AI First Flight #6
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Severity: medium
Valid

Burning or blocking a profile permanently strands its unmatched ETH balance

Summary

A user's pending like funds are tied to their address in LikeRegistry.userBalances, but neither voluntary profile burning nor owner blocking refunds that balance. Once the profile is removed, the address fails the profile checks required to participate in a future mutual match, and the registry exposes no refund or cancellation function.

Root cause and evidence

SoulboundProfileNFT.burnProfile and blockProfile at lines 43-66 burn the NFT and delete profileToToken without coordinating with LikeRegistry. LikeRegistry.likeUser at lines 35-36 requires both parties to still have profiles, while the contract has no function that lets a user withdraw an unmatched balance.

After the intended missing credit in likeUser is fixed, a user can deposit ETH in one or more pending likes and then burn their profile, or be blocked by the owner. Their balance remains in the registry, but no new mutual match can settle it.

Impact

Legitimate users can permanently lose all ETH committed to pending likes through a normal supported action or an administrative block.

Minimal patch

Add an explicit cancellation/refund path in LikeRegistry using checks-effects-interactions: read the refundable unmatched balance, set it to zero, then transfer it to the user. Coordinate burning/blocking with the registry so pending funds are returned before profile state is deleted. Keep already-settled multisig funds out of this path.

Regression test

Credit a user's pending balance, burn or block the profile, execute the refund flow, and assert the user receives the full unmatched amount and the registry balance entry becomes zero. Also assert a second refund reverts.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 2 hours ago
Submission Judgement Published
Validated
Assigned finding tags:

[M-03] App owner can have users' funds locked by blocking them

## Description App owner can block users at will, causing users to have their funds locked. ## Vulnerability Details `SoulboundProfileNFT::blockProfile` can block any app's user at will. ```js /// @notice App owner can block users function blockProfile(address blockAddress) external onlyOwner { uint256 tokenId = profileToToken[blockAddress]; require(tokenId != 0, "No profile found"); _burn(tokenId); delete profileToToken[blockAddress]; delete _profiles[tokenId]; emit ProfileBurned(blockAddress, tokenId); } ``` ## Proof of Concept The following code demonstrates the scenario where the app owner blocks `bob` and he is no longer able to call `LikeRegistry::likeUser`. Since the contract gives no posibility of fund withdrawal, `bob`'s funds are now locked. Place `test_blockProfileAbuseCanCauseFundLoss` in `testSoulboundProfileNFT.t.sol`: ```js function test_blockProfileAbuseCanCauseFundLoss() public { vm.deal(bob, 10 ether); vm.deal(alice, 10 ether); // mint a profile NFT for bob vm.prank(bob); soulboundNFT.mintProfile("Bob", 25, "ipfs://profileImage"); // mint a profile NFT for Alice vm.prank(alice); soulboundNFT.mintProfile("Alice", 25, "ipfs://profileImage"); // alice <3 bob vm.prank(alice); likeRegistry.likeUser{value: 1 ether}(bob); vm.startPrank(owner); soulboundNFT.blockProfile(bob); assertEq(soulboundNFT.profileToToken(msg.sender), 0); vm.startPrank(bob); vm.expectRevert("Must have a profile NFT"); // bob is no longer able to like a user, as his profile NFT is deleted // his funds are effectively locked likeRegistry.likeUser{value: 1 ether}(alice); } ``` And run the test: ```bash $ forge test --mt test_blockProfileAbuseCanCauseFundLoss Ran 1 test for test/testSoulboundProfileNFT.t.sol:SoulboundProfileNFTTest [PASS] test_blockProfileAbuseCanCauseFundLoss() (gas: 326392) Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.42ms (219.63µs CPU time) Ran 1 test suite in 140.90ms (1.42ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests) ``` ## Impact App users can have their funds locked, as well as miss out on potential dates. ## Recommendations Add a voting mechanism to prevent abuse and/or centralization of the feature.

Support

FAQs

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

Give us feedback!