Soulmate::ownerToId
returns the soulmate NFT id that is associated with the soulmate participating in the contract but it return 0 as id if the user has not participated in the protocol (i.e. has no soulmate).
As the token id starts from 0, thus token id - 0 is actually assigned to soulmates, but Soulmate::ownerToId
returning 0 for non-soulmates user lead to potential loss of soulmates whose id is actually 0 as well as allows the non-soulmates users to enjoy the same benefits (of Airdrop & Staking), soulmates with id = 0 are enjoying.
The vulnerability occurs due to starting tokenId for Soulmate NFT from 0 in Soulmate
contract as Soulmate::ownerToId
returns 0 for non-soulmate users.
Thus, these non-soulmate users can hinder with the soulmates with id = 0
with malicious intent and can cause danger to their relation (in worst case may also lead to their divorce) as well as allows them to take benefit of Airdrop as well as Staking without having any soulmates.
Airdrop::claim
function uses Soulmate::ownerToId
to calculate the numberOfDaysInCouple
as follows:
For non-soulmate users calling claim function, ownerToId
will be evaluated as 0, thus the numberOfDaysInCouple
is calculated considering them as soulmates with id = 0
, allowing all non-soulmate users to claim Airdrop.
Soulmate::writeMessageInSharedSpace
allows soulmates to share messages with them and should not allow non-soulmate users or other soulmates to hinder with their messaging.
But ownerToId
returning 0 for all non-soulmate users will allow them to hinder and manipulate the messages of soulmates with id = 0
.
Therefore, allowing malicious users to put up hate messages in the shared space of soulmates with id = 0
and they can end up divorcing due to other malicious users circulating hate messages in their shared space.
Staking::claimRewards
allows users to claim rewards for their staked amount, but soulmateId
calculated for the caller evaluates to 0 for non-soulmate users giving them benefits even if they have not staked their amount for a week or more.
Add the below test in file: test/unit/AirdropTest.t.sol
and also import console2
from BaseTest.t.sol
inside the AirdropTest.t.sol
Run the test:
Add the below test in the file: test/unit/SoulmateTest.t.sol
Run the test:
Manual Review, Unit Test in Foundry
Start token id from 1 instead of 0 and along with that Soulmate::ownerToId
should revert if it is 0.
At line 32 in Soulmate
Make the mapping declaration private at line 26 in Soulmate
As we have changed the name from ownerToId
to _ownerToId
(added a underscore), thus update all the positions inside Soulmate contract where it is updated (at line 72 and 77)
Implement the actual function with name ownerToId
which reverts when the user doesn't have any token (i.e. their id = 0)
High severity, This issue is separated from the flawed `isDivorced()` check presented in issue #168 as even if that is fixed, if ownership is not checked, isDivorced would still default to false and allow bypass to claim airdrops by posing as tokenId 0 in turn resulting in this [important check for token claim is bypassed.](https://github.com/Cyfrin/2024-02-soulmate/blob/b3f9227942ffd5c443ce6bccaa980fea0304c38f/src/Airdrop.sol#L61-L66). #220 is the most comprehensive issue as it correctly recognizes both issues existing within the same function.
- Given the native anonymous nature of blockchain in general, this issue cannot be avoided unless an explicit whitelist is implemented. Even then we can only confirm soulmates are distinct individuals via kyc. I believe finding a soulmate is intended to be permisionless. - However, even though sufficient (500_000_000e18 in each vault) tokens are minted to claim staking and airdrop rewards, it would take 500_000_000 / 2 combined weeks for airdrop vault to be drained which is not unreasonable given there are [80+ million existing wallets](https://coinweb.com/trends/how-many-crypto-wallets-are-there/). Given there is no option to mint new love tokens, this would actually ruin the functionality of the protocol of finding soulmates and shift the focus to abusing a sybil attack to farming airdrops instead. Assigning medium severity for now but am open for appeals otherwise, since most if not all issues lack indepth analysis of the issue.
Medium Severity, This has an indirect impact and influence on the possibility of divorce between soulmates owning the first soulmate NFT id0, leading to permanent loss of ability to earn airdrops/staking rewards.
High severity, as it allows any pending user to claim staking rewards without owning a soulmate NFT by - Obtaining love tokens on secondary markets - Transfer previously accrued love tokens via airdrops/rewards to another account and abusing the `deposit()` function
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.