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

tokenURI function missing equal distribution behavior

Summary

The tokenURI function does not meet the requirements for equal distribution.

Vulnerability Details

The Documentation reports:

You'll see the tokenURI function returns one of 4 random Mondrian art paintings. Each should have equal distribution and be random.

The tokenURI method MondrianWallet.sol#L161-L175 can return one of the four Mondrian Paintings but not uniformly.
The code of the function is:

function tokenURI(uint256 tokenId) public view override returns (string memory) {
if (ownerOf(tokenId) == address(0)) {
revert MondrainWallet__InvalidTokenId();
}
uint256 modNumber = tokenId % 10;
if (modNumber == 0) {
return ART_ONE;
} else if (modNumber == 1) {
return ART_TWO;
} else if (modNumber == 2) {
return ART_THREE;
} else {
return ART_FOUR;
}
}

The computation of the painting to be returned is made upon the use of modulus operator, where the second operand is 10.
However to guarantee an equal distribution on the returned value, the function should match uniformly all the possibile remainders returned by the modulus operator, and that's not the case because the mapping beetween the input value and the output value is:

modNumber tokenURI
0 ART_ONE
1 ART_TWO
2 ART_THREE
3 ART_FOUR
4 ART_FOUR
5 ART_FOUR
6 ART_FOUR
7 ART_FOUR
8 ART_FOUR
9 ART_FOUR

The output distribution is: ART_ONE=10%, ART_TWO=10%, ART_THREE=10%, ART_FOUR=70%, definetly not uniform as the expectation.

Impact

Missing the equal distribution for the paintings could have an impact for the secondary market of MondianWallet NFT, leading to the disruption of the market equilibrium.

Tools Used

The code has been visual inspected

Recommendations

Let the second operand of the modulus be 4, to match uniformly all the available paintings. The function code should be (diff included):

function tokenURI(uint256 tokenId) public view override returns (string memory) {
if (ownerOf(tokenId) == address(0)) {
revert MondrainWallet__InvalidTokenId();
}
- uint256 modNumber = tokenId % 10;
+ uint256 modNumber = tokenId % 4;
if (modNumber == 0) {
return ART_ONE;
} else if (modNumber == 1) {
return ART_TWO;
} else if (modNumber == 2) {
return ART_THREE;
} else {
return ART_FOUR;
}
}
Updates

Lead Judging Commences

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

NFT's should have equal distribution

Support

FAQs

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