Pieces Protocol

First Flight #32
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Single Mapping per NFT Address (Ignoring `tokenId`)

Description

The mapping nftToErc20Info is defined as:

mapping(address nft => ERC20Info) nftToErc20Info;

It stores only one ERC20Info struct per NFT contract address, without considering the tokenId. In many NFT collections, there are multiple token IDs under the same contract. By using nftToErc20Info[nftAddress], the system supports only one fractioned NFT per contract address. Fractioning a second token (tokenId) on the same NFT contract overwrites the information from the first fractioned token.

Impact

  1. Collision Overwrites: Fractioning another tokenId from the same NFT contract overwrites the previous fraction data (erc20 address, balances, etc.).

  2. Loss of Ownership Records: Original fraction owners of tokenId = 1 may lose their claims if the fraction info for tokenId = 2 is written into the same slot.

  3. Inability to Claim: If tokenId mismatch occurs, no one can claim the originally fractioned NFT because that data is lost.

Attack Route

  1. Honest user fractionizes tokenId = 0. The contract stores that fraction info in nftToErc20Info[nftAddress].

  2. A second user calls divideNft(nftAddress, tokenId = 1, someAmount). The contract overwrites the same entry in nftToErc20Info[nftAddress], effectively destroying or hijacking the fraction records for tokenId = 0.

Recommendation

  • Change nftToErc20Info to a double-mapping that keys both the NFT contract address and the tokenId. For instance:

    mapping(address => mapping(uint256 => ERC20Info)) public nftToErc20Info;
  • Reflect this change throughout the contract (e.g., claimNft, sellErc20, transferErcTokens, etc.) so that each token ID has its own fraction data.

Updates

Lead Judging Commences

fishy Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Wrong nft collection handling

Support

FAQs

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

Give us feedback!