If a user tries to bridge an NFT of a L1-native collection that uses a baseURI to L2, the NFT's metadata will not be reflected on L2 causing loss of information about the NFT.
The L2 bridge, when withdrawing NFTs with withdraw_auto_from_l1, only mints NFTs with uris if there are uris in the uris array of the request. L1 on the other hand uses a baseURI if the collection supports it. This means that if we bridge an NFT with a baseURI to L2, the NFT's uri will not be reflected as it will be minted with mint_from_bridge instead of mint_from_bridge_uri.
This can be seen at [1]. If uris is empty we do not mint with a URI even if there is a base_uri specified in the request.
This means that a NFT's uri may not be reflected on L2 when bridging. Since the uri points to crucial information about an NFT like the image associated with it, this causes major inconvenience for the users, impacting the protocol's reputation.
Since the baseURI functionality on L1 is currently broken, building an end-to-end PoC for this requires fixing this issue first. Therefore I will step through the code to show the bug.
Initial state:
NFT deployed on L1 with baseURI
NFT deployed on L2 without any metadata yet as it is just there to receive the L1-native NFTs with their metadata
Entrypoint: Bridge::depositTokens
Here at [1], we retrieve the token's metadata. If the token has a baseURI set, this should be taken, leaving the tokenURIs empty.
TokenUtil::erc721Metadata
This can be seen at [2].
Now let's look at the receiving side (L2):
bridge::withdraw_auto_from_l1
At [3], we would handle the minting with URIs if the uris array is non-empty. Since our request only contains a base_uri and no uris, this path is not taken. Instead we take the path at [4], meaning we call mint_from_bridge which does not touch the NFT's metadata.
erc721_bridgeable::mint_from_bridge
Manual review
This can be fixed by adding another check after if (req.uris.len() != 0) for whether req contains a base_uri and if so, mint the NFT with the proper URI, ensuring its metadata is preserved on L2.
URI is not lost on the origin chain and it can be modified with `ERC721UriImpl`. As explained in the TODO below, that’s a design choice and it will be implemented as a future feature. https://github.com/Cyfrin/2024-07-ark-project/blob/main/apps/blockchain/ethereum/src/Bridge.sol#L206 `ERC721Bridgable` is out of scope.
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.