DatingDapp

AI First Flight #6
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

burnProfile() can orphan pending like funds with no recovery or refund path

Root + Impact

Description

  • Users are allowed to delete their profile by calling burnProfile().

  • The registry separately stores persistent like state, match state, and user balance state, but there is no cleanup, refund, or settlement hook when a profile is burned.

  • Once a user burns their profile, they can lose eligibility for future matching while any ETH already committed through the registry remains trapped in LikeRegistry.

  • The system therefore allows state in SoulboundProfileNFT and LikeRegistry to diverge, leaving pending user funds with no recovery mechanism

function burnProfile() external {
uint256 tokenId = profileToToken[msg.sender];
require(tokenId != 0, "No profile found");
require(ownerOf(tokenId) == msg.sender, "Not profile owner");
​
@> _burn(tokenId);
@> delete profileToToken[msg.sender];
@> delete _profiles[tokenId];
​
emit ProfileBurned(msg.sender, tokenId);
}
​
// LikeRegistry has no corresponding refund, cleanup, or withdrawal path
mapping(address => uint256) public userBalances;
mapping(address => mapping(address => bool)) public likes;
mapping(address => address[]) public matches;
​

Risk

Likelihood:

  • Any user can trigger this by deleting their own profile after funding likes.

  • The issue can occur during normal use, especially when users leave the app before a mutual match is formed.

Impact:

  • ETH associated with pending likes can become permanently stranded.

  • Protocol state becomes inconsistent because profile existence and escrowed funds are no longer synchronized

Proof of Concept

// 1. Alice mints a profile and likes Bob with ETH
// 2. Bob has not yet liked Alice back
// 3. Alice calls burnProfile()
// 4. Alice no longer has a profile NFT, but her like-related balance remains in LikeRegistry
// 5. There is no function that lets Alice reclaim or settle the pending funds
​

Recommended Mitigation

The safer design is to either refund and clear registry state before burning, or block profile deletion until the registry state is fully resolved.

// Option 1: prevent profile deletion while funds or pending likes exist
function burnProfile() external {
+ require(!likeRegistry.hasPendingExposure(msg.sender), "Pending likes or funds exist");
uint256 tokenId = profileToToken[msg.sender];
require(tokenId != 0, "No profile found");
require(ownerOf(tokenId) == msg.sender, "Not profile owner");
_burn(tokenId);
delete profileToToken[msg.sender];
delete _profiles[tokenId];
emit ProfileBurned(msg.sender, tokenId);
}
​
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!