The fact that short.tokenId starts from 0 will lead to incorrect behaviour of the functions : ShortRecordFacet.combineShorts, ERC721Facet.balanceOf, ERC721Facet.mintNFT as they all assume that the short tokenId starts from 1 (cannot be 0).
The issue occurs when the first short is minted with the ERC721Facet.mintNFT function :
As you can see from the code above the s.tokenIdCounter is first assigned to short.tokenId before its value get incremented, and because s.tokenIdCounter is never initialized to 1 this will result in the first short having a tokenId equal to 0.
This will lead an incorrect behaviour in three functions of the protocol : ERC721Facet.balanceOf, ERC721Facet.mintNFT and ShortRecordFacet.combineShorts.
First we start ERC721Facet.mintNFT itself, we can see from the code snippet above that because the first short have a tokenId equal to 0, the shorter can mint a second NFT for the same short as the check if (short.tokenId != 0) revert Errors.AlreadyMinted(); will not revert.
In the ERC721Facet.balanceOf functions we find that if counts only the NFTs with tokenId different from 0 and so this first short NFT will not be accounted for in the shorted balance.
And finally in ShortRecordFacet.combineShorts function there is the following lines of code :
We find the function will always misbehave when the first minted short record NFT is used, if it's currentShort then the check currentShort.tokenId != 0 will be false and thus the NFT won't be burned which is wrong, and in the other case if it's firstShort the check will firstShort.tokenId == 0 will be true and the call will revert which is not supposed to happen.
The fact that short.tokenId starts from 0 will lead to incorrect behaviour of the functions : ShortRecordFacet.combineShorts, ERC721Facet.balanceOf, ERC721Facet.mintNFT as they all assume that the short tokenId starts from 1 (cannot be 0).
Manual review
Make sure that short.tokenId starts from 1 by first incrementing s.tokenIdCounter and then assigning its value, this avoid any misbehaviour of the aforementioned functions :
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.