The claimNft function fails when multiple NFTs from the same collection (nftAddress) are divided because the nftToErc20Info mapping is overwritten. This results in incorrect ERC20Info being retrieved, which causes the function to revert when users attempt to claim their NFTs.
The nftToErc20Info mapping stores information using only the NFT collection address (nftAddress) as the key. This means it can't differentiate between multiple tokens in the same collection, leading to overwriting. This allows the mapping to be overwritten when a new token from the same NFT collection is divided. As a result, the ERC20Info for the NFT being claimed may no longer be valid:
The claimNft function relies on the nftToErc20Info mapping to retrieve the corresponding ERC20Info. If the mapping has been overwritten, the erc20Address and tokenId values will be incorrect, leading to a revert in this line as the user's balance will be less than the amount of that token that was minted since that is not the token associated with the NFT the user wished to claim:
User A divides an NFT from nftAddress with tokenId = 1.
The mapping is updated: nftToErc20Info[nftAddress] = ERC20Info({erc20Address: <erc20Address1>, tokenId: 1}).
User B divides another NFT from the same nftAddress but with tokenId = 2.
The mapping is overwritten: nftToErc20Info[nftAddress] = ERC20Info({erc20Address: <erc20Address2>, tokenId: 2}).
User A tries to claim their NFT with tokenId = 1. The claimNft function retrieves the incorrect ERC20Info for tokenId = 2.
The function reverts because the balances and erc20ToMintedAmount checks are based on the wrong ERC20Info.
In the TokenDividerTest.t.sol file, do the following:
Replace your setup function with this:
Add two new variables at the top of the test contract
Now copy this test and add it to your file:
Run this command in your terminal:
This test will fail with the error TokenDivider__NotEnoughErc20Balance() just like I said it would.
Users cannot claim their NFTs because the mapping points to an incorrect ERC20Info.
This can lead to a loss of user trust, as they are unable to retrieve their assets due to the contract's faulty design.
Manual code review
Foundry
To resolve this issue,
Modify the nftToErc20Info mapping in line 59 to account for both nftAddress and tokenId.
Update the divideNft function in line 127 to correctly store the ERC20Info for each unique token:
Update the claimNft, transferErcTokens, sellErc20, and getErc20InfoFromNft functions to take in the correct arguments:
In line 147
In line 179:
In line 221:
In line 319:
Finally, correct all instances where the mapping is called to fetch the correct ERC20Info:
In line 153:
In line 193:
In line 230:
In line 320:
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.