Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

Weak randomness in the `Soulmate::mintSoulmateToken` function that allows malicious users to influence the time when the `Soulmate` token has been minted.

Description: On the Protocol level, the variable block.timeStamp is being used to influence the time when a Soulmate token has been minted. The global variable block.timeStamp does not necessarily hold the current time, and may not be accurate. Miners can influence the value of block.timeStamp to perform Maximal Extractable Value (MEV) attacks thus prioritising a certain time to mint the Soulmate token.

function mintSoulmateToken() public returns (uint256) {
address soulmate = soulmateOf[msg.sender];
if (soulmate != address(0)) {
revert Soulmate__alreadyHaveASoulmate(soulmate);
}
address soulmate1 = idToOwners[nextID][0];
address soulmate2 = idToOwners[nextID][1];
if (soulmate1 == address(0)) {
idToOwners[nextID][0] = msg.sender;
ownerToId[msg.sender] = nextID;
emit SoulmateIsWaiting(msg.sender);
} else if (soulmate2 == address(0)) {
idToOwners[nextID][1] = msg.sender;
ownerToId[msg.sender] = nextID;
soulmateOf[msg.sender] = soulmate1;
soulmateOf[soulmate1] = msg.sender;
@> idToCreationTimestamp[nextID] = block.timestamp;
emit SoulmateAreReunited(soulmate1, soulmate2, nextID);
_mint(msg.sender, nextID++);
}
return ownerToId[msg.sender];
}

Note: This additionally means users could front-run this function and influence a certain time to mint the soulMate token.

Impact: Any user can influence when the Soulmate token has been minted thus making the protocol to register a false current time in the Soulmate::idToCreationTimestamp mapping.

Proof of Concept:

  1. A malicious user can influence the current time let's say to 1 week ahead which is equivalent to 604_800 seconds.

  2. The Soulmate::idToCreationTimestamp then records the altered current time to be the set 604_800 seconds/ 1week.

Proof Of Code

Place the following into the SoulmateTest.t.sol.

function test_CurrentTimeCanBeManipulatedByUser() public {
uint256 nextId;
vm.warp(1 weeks);
vm.prank(soulmate1);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate2);
soulmateContract.mintSoulmateToken();
assertEq(vm.getBlockTimestamp(), 1 weeks, "timestamp should be 1 week");
assertEq(soulmateContract.idToCreationTimestamp(nextId), 1 weeks);
}

Recommended Mitigation: Consider using an off-chain Oracle to get the accurate present time for minting the Soulmate token.

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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