DatingDapp

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

`likes`/`matches` are never cleared on `burnProfile`/`blockProfile`, causing stale cross-contract state and a permanent re-like lockout

Description

Normal behavior: the soulbound profile is a user's identity in the dapp, and deleting it — either by the user via burnProfile or by the owner via blockProfile — is meant to be a clean removal. After a self-burn a user should be able to re-mint a fresh profile and use the app normally again; after an owner block the user should be fully removed from the system. A user's dating state (their likes, their matches) is tied to that identity and should stay consistent with whether the identity still exists.

Specific issue: profile deletion and the dating state live in two different contracts that are never kept in sync. SoulboundProfileNFT.burnProfile/blockProfile delete only the NFT-side mappings (profileToToken, _profiles); they never call into LikeRegistry, so LikeRegistry.likes and matches survive the burn untouched. This produces several concrete problems:

  1. Permanent re-like lockout. likeUser gates on require(!likes[msg.sender][liked], "Already liked"). Because likes[user][x] is keyed by ADDRESS (not tokenId) and is never cleared, a user who burns and re-mints — getting a brand-new tokenId and ostensibly a fresh start — still has likes[user][x] == true forever and can NEVER like that person again. There is no unlike/reset function to clear it.

  2. Stale matches. matches[user] still lists counterparties from before a burn; getMatches() and any app or owner view returns stale, incorrect data.

  3. Ineffective moderation. When the owner blocks a user (or both users of a pair) via blockProfile, their NFTs are removed but their likes/matches remain true, and any already-deployed MultiSigWallet (and its funds/control) is entirely unaffected. Blocking does not actually remove the user from the social graph or the fund flow.

// SoulboundProfileNFT.burnProfile / blockProfile: delete NFT state ONLY
delete profileToToken[msg.sender]; delete _profiles[tokenId]; // @> LikeRegistry.likes/matches never touched
// LikeRegistry.likeUser
require(!likes[msg.sender][liked], "Already liked"); // @> stale `true` persists across burn+remint

Risk

Likelihood:

  • Deterministic for any user who burns and re-mints (a documented, intended action) or who is blocked by the owner.

  • Users will routinely burn/re-mint to change a profile and immediately hit the stale likes.

Impact:

  • Permanent, irreversible lockout from a core action (re-liking a previous like) after a legitimate profile reset.

  • Corrupted/stale social-graph state (likes, matches) exposed to the app and to owner moderation, and moderation that fails to actually sever the blocked user's relationships or fund access.

Proof of Concept

test/SeamAudit.t.sol::test_F2_likesPersistAcrossBurnRemint_permanentLockout (PASS): after burn+re-mint, likes(alice,bob) is still true and re-liking reverts "Already liked". test_F2b_ownerBlockLeavesStaleMatch (PASS): after blocking both users, getMatches() still returns the stale match.

Recommended Mitigation

Expose a registry hook the NFT calls on burn/block to clear likes/matches for that user (or add an unlike), so profile deletion resets the dating state consistently across both contracts.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 2 hours 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!