Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: low
Invalid

Non-Unique Metadata for All Token IDs

Summary

location : FlowNFTDescriptor.sol

The tokenURI function is intended to return metadata specific to each NFT based on its streamId. However, in the current implementation, the function does not utilize the streamId parameter or the sablierFlow contract reference. As a result, it generates the same metadata for every NFT, regardless of its unique identifier.

code :

function tokenURI(
IERC721Metadata, /* sablierFlow */
uint256 /* streamId */
)
external
pure
override
returns (string memory uri)
{
// Function body does not use 'streamId' or 'sablierFlow'
// Returns the same 'uri' for all tokens
}

Impact

  • NFT Uniqueness Compromised: Each NFT should have unique metadata to reflect its specific attributes and ownership details. Identical metadata can cause confusion and make it difficult for platforms and users to distinguish between different NFTs.

  • Potential for Misrepresentation: Without unique identifiers in the metadata, there is an increased risk of misrepresentation or fraudulent activities, as all tokens appear identical in metadata content.

Tools Used

Manual Review

Recommendations

  • Utilize the streamId and sablierFlow Parameters: Modify the tokenURI function to incorporate the streamId and interact with the sablierFlow contract to retrieve stream-specific data.

  • Generate Dynamic Metadata: Include stream-specific details such as stream amount, recipient, sender, start and end times in the metadata JSON.

  • Customize SVG Content: Consider generating the SVG image dynamically to reflect unique aspects of each stream, enhancing the visual distinction between NFTs.


Example Modification:

function tokenURI(
IERC721Metadata sablierFlow,
uint256 streamId
)
external
view
override
returns (string memory uri)
{
// Retrieve stream details using 'sablierFlow' and 'streamId'
// (Assuming 'sablierFlow' has a function 'getStreamData' returning relevant data)
StreamData memory streamData = sablierFlow.getStreamData(streamId);
// Create dynamic SVG or metadata based on 'streamData'
string memory svg = generateSVG(streamData);
string memory image = string.concat(
"data:image/svg+xml;base64,",
Base64.encode(bytes(svg))
);
// Construct JSON metadata with unique attributes
string memory json = string.concat(
'{"description": "This NFT represents a payment stream in Sablier Flow.",',
'"external_url": "https://sablier.com/streams/', Strings.toString(streamId), '",',
'"name": "Sablier Flow Stream #', Strings.toString(streamId), '",',
'"attributes": [',
'{"trait_type": "Recipient", "value": "', Strings.toHexString(uint256(uint160(streamData.recipient)), 20), '"},',
'{"trait_type": "Amount", "value": "', Strings.toString(streamData.amount), '"},',
'{"trait_type": "Start Time", "value": "', Strings.toString(streamData.startTime), '"},',
'{"trait_type": "End Time", "value": "', Strings.toString(streamData.endTime), '"}',
'],',
'"image": "', image, '"}'
);
uri = string.concat(
"data:application/json;base64,", Base64.encode(bytes(json))
);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

[INVALID] Non-Unique Metadata

Support

FAQs

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