The LikeRegistry
smart contract allows users to like other users and get all payments upon mutual likes through a matchmaking system. However, the contract is vulnerable to an attack where malicious users can exploit the system by baiting others, pooling out all his payments, and still getting matched with other users despite having a zero balance. This creates an unfair advantage for attackers and compromises the integrity of the matchmaking system.
likes
Mapping and Balance ResetThe likes
mapping is not reset after a match is made. This allows attackers to repeatedly exploit users who previously liked them.
The contract does not validate whether the msg.sender
has a non-zero balance before performing operations in the likeUser
function.
The provided PoC demonstrates how the attacker uses their own accounts to bait and drain funds, while still benefiting from matches with other users despite having no balance left.
An attacker (AttackerAddress1) and their second account (AttackerAddress2) mint Soulbound NFTs to participate in the matchmaking system.
AttackerAddress2 likes AttackerAddress1 to bait other users by increasing their match potential.
Innocent users like AttackerAddress1, contributing funds to the attacker's balance.
The attacker triggers a self-match between AttackerAddress1 and AttackerAddress2, withdrawing their entire balance through the matchRewards
function.
Despite having a zero balance, AttackerAddress1 can still get matched with previously interacting users due to the persistent likes
mapping and exploit funds from other innocent users.
Here is the code the prove the scenario. Create a new test file LikeRegistryTest.t.sol
and add to the test/
directory.
Then run the command below;
The vulnerability allows an attacker to:
withdraw all their funds via a self-match without resetting the likes
mapping.
Exploit innocent users who have previously liked them, resulting in repeated matches and unfair rewards.
Foundry: Used to write and execute the PoC test cases (forge-std
library).
Manual Review
To address the vulnerability, the following recommendations should be implemented:
Add a check to ensure that the msg.sender
has a balance greater than 0 in LikeRegistry::matchRewards
before proceeding with a match.
likes
Mapping After a MatchIntroduce an array to track all users who liked a particular user and iterate over it to reset the likes
mapping after a match in LikeRegistry::likeUser
.
Likelihood: Medium, if anyone has 2 matches or more before reliking. Impact: Medium, the user won't contribute to the wallet.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.