The contract assumes that one user will convert only 1 NFT from an NFT address into ERC20. What if user has minted 2 NFTs from an NFT address? In such case if User wants to convert second NFT from same NFT Address into ERC20. The previous information is overridden.
If there are multiple NFTs minted from same NFT address for the user. And user converts both NFTs into ERC20 one aftre another, "mapping(address nft => ERC20Info) nftToErc20Info;" is overridden. Previous ERC20Info is lost and replaced by recent ERC20Info.
To replication this following can be done -
Step 1 - User divides the first NFT (Token Id 0)
Step 2 - User gets (mints) second NFT from same ERC721 (Token id 1). Do a console.logAddress(tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address)
Step 3 - User divides the second NFT (Token id 1). Notice that eRC20 Address has been overridden now.Do a console.logAddress(tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address)
Notice that cosole log after Step 3 returns a different value for ERC20Address that Step 2.
Following is the POC. Just paste this test in TokenDividerTest.t.sol and run the test as "forge test -vv --match-test testNFTERCAssociation". Notice that console.log returns different values.
This is a logical flaw. Contract assumes that user cannot convert second NFT from same NFT address.
Data loss as the previous ERC20 Information is lost.
Impacts other functions which use nftToErc20Info variable like claimNFT, transferErcTokens
Foundry
This can be resolved in couple of ways -
In divideNFT add a check if NFT Address is already associated with ERC20 token. Use the same token to mint more NFTs for user.
OR
"mapping(address nft => ERC20Info) nftToErc20Info;" should me "mapping(address nft => mapping(address ERC20 => tokenid)" etc
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.