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

Any user without a soulmate can write a message in the shared space for tokenId=0.

Summary

The protocol is supposed to only allow soulmates with the same NFT ID to write in a shared space. However, any user without a soulmate can write a message in the shared space dedicated for soulmates with an NFT ID of 0.

Vulnerability Details

The default value for uint256 is 0, which means that the mapping Soulmate::ownerToId returns 0 for both users with a valid NFT ID of 0 and users who do not own any NFT ID. Hence, virtually, any user without an NFT can call Soulmate::writeMessageInSharedSpace and write a message to sharedSpace[0].

The following PoC can be added to SoulmateTest.t.sol to verify this issue.

function test_SingleSoulCanWriteMessage() public {
uint tokenIdMinted = 0;
address singleSoul = makeAddr("singleSoul");
string memory msgFromSingleSoul = "Single soul can write!";
// soulmate1 and soulmate2 own NFT of which ID is 0
vm.prank(soulmate1);
soulmateContract.mintSoulmateToken();
assertTrue(soulmateContract.totalSupply() == 0);
vm.prank(soulmate2);
soulmateContract.mintSoulmateToken();
assertTrue(soulmateContract.totalSupply() == 1);
assertTrue(soulmateContract.ownerToId(soulmate1) == tokenIdMinted);
// a user without any soulmate can write to shared space
// of soulmate1 and soulmate 2
vm.prank(singleSoul);
soulmateContract.writeMessageInSharedSpace(msgFromSingleSoul);
vm.prank(soulmate1);
console2.log(soulmateContract.readMessageInSharedSpace());
}

As shown below, the user with an NFT ID of 0 (soulmate1) reads a message that is written by a random user.

Running 1 test for test/unit/SoulmateTest.t.sol:SoulmateTest
[PASS] test_SingleSoulCanWriteMessage() (gas: 245408)
Logs:
Single soul can write!, darling

Impact

The impact of this vulnerability is HIGH because valid legitimate users who own an NFT with an ID of 0 are impacted. Furthermore, the protocol did not intend to allow any random users who don`t have soulmates to spam messages and virtually share the message space among them.

Tools Used

Foundry

Recommendations

There are several options to mitigate this issue. The simplest fixes would be

  1. Use 1 as the 1st minted NFT`s ID, instead of 0.

  2. Allow a user to write a message in as shared space only if the user has a soulmate by adding a check in Soulmate::writeMessageInSharedSpace.

function writeMessageInSharedSpace(string calldata message) external {
+ if (soulmateOf[msg.sender] == address(0))
+ revert Soulmate__doesNotHaveASoulmate();
uint256 id = ownerToId[msg.sender];
sharedSpace[id] = message;
emit MessageWrittenInSharedSpace(id, message);
}
Updates

Lead Judging Commences

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

finding-write-message-nft-0-id

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.

Support

FAQs

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