DatingDapp

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

Missing Unlike Function Vulnerability in LikeRegistry Contract

Description

The LikeRegistry contract lacks functionality to revoke or "unlike" a profile, creating significant risks for users who need to dissociate from malicious actors, impersonators, or simply change their mind. This limitation locks users into permanent associations and their 1 ETH deposits.

The contract only implements one-way liking functionality through likeUser():

function likeUser(address liked) external payable {
require(msg.value >= 1 ether, "Must send at least 1 ETH");
require(!likes[msg.sender][liked], "Already liked");
likes[msg.sender][liked] = true;
// ... rest of function
}

Impact:

  • Locked funds if match is undesirable

  • Users are permanently associated with potential impersonators

  • Vulnerability to social engineering attacks

  • Increased exposure to scams

Vulnerability Details

  • Impersonator creates profile mimicking popular user

  • Victim likes impersonator's profile

  • Victim discovers deception but cannot unlike

  • Impersonator can force a match by liking back

  • Both users are permanently linked with no recourse

Proof of Concept

The following test demonstrates the inability to unlike and its associated risks:

function testCannotUnlike() public {
address maliciousImpersonator = makeAddr("impersonator");
vm.deal(user, 2 ether);
vm.deal(maliciousImpersonator, 2 ether);
// Create legitimate profiles
vm.prank(user);
soulboundNFT.mintProfile("Alice", 25, "ipfs://Alice");
vm.prank(user2);
soulboundNFT.mintProfile("Bob", 28, "ipfs://bob");
// Impersonator creates similar profile to Bob
vm.prank(maliciousImpersonator);
soulboundNFT.mintProfile("Bob", 28, "ipfs://bob");
// Alice likes what she thinks is Bob's profile
vm.prank(user);
likeRegistry.likeUser{value: 1 ether}(maliciousImpersonator);
// Alice discovers it's an impersonator
// But she cannot unlike or recover her ETH
vm.prank(user);
// No unlike function exists
// likeRegistry.unlikeUser(maliciousImpersonator);
// Verify Alice is permanently linked
assertTrue(likeRegistry.likes(user, maliciousImpersonator));
// If impersonator likes back, they're permanently matched
vm.prank(maliciousImpersonator);
likeRegistry.likeUser{value: 1 ether}(user);
// Verify forced match that cannot be broken
vm.prank(user); // Alice
address[] memory aliceMatches = likeRegistry.getMatches();
assertEq(aliceMatches[0], maliciousImpersonator);
}

Fix Recommendation:

  • Implement unlike functionality

Tools Used

  • Foundry Testing Framework

  • Manual Review

Updates

Appeal created

n0kto Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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