NFTBridge
60,000 USDC
View results
Submission Details
Severity: low
Valid

Case Sensitivity Flaw in ERC721 baseURI Function Results in Missing Metadata on L2.

Summary

in ERC721 functions there is no baseUri
instead the function is called baseURI, this discrepancy leads to a failure
in generating the expected bytes4 selector, causing the URI to remain empty, and when these tokens are bridged to starknet L2
they will have empty URI.

Vulnerability Details

The issue arises due to the incorrect casing of the baseURI function, which is a standard method used in ERC721 contracts
to return the base URI for token metadata.

When the function is named baseUri
with a lowercase Uri instead of URI, the generated bytes4 selector will be different
from the standard baseURI selector. As a result, calls to baseURI return false and empty Uri.

- baseUri: 0x9abc8320
+ baseURI: 0x6c0360eb

POC: https://github.com/Cyfrin/2024-07-ark-project/blob/main/apps/blockchain/ethereum/src/token/TokenUtil.sol#L150

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "hardhat/console.sol";
contract Test {
function init() public {
(bool s, string memory uri) = _callBaseUri(address(this));
@>>> // this will return false and empty uri
@>>> console.log("Result::", s, uri);
}
// ERC721 baseURI function name.
function baseURI() public view returns(string memory) {
return "ipfs://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/";
}
function _callBaseUri(address collection) internal view returns (bool, string memory) {
bool success;
uint256 returnSize;
uint256 returnValue;
bytes memory ret;
bytes[2] memory encodedSignatures = [
@>>> abi.encodeWithSignature("_baseUri()"),
@>>> abi.encodeWithSignature("baseUri()")
];
for (uint256 i = 0; i < 2; i++) {
bytes memory encodedParams = encodedSignatures[i];
assembly {
@>>> success := staticcall(gas(), collection, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
if success {
returnSize := returndatasize()
returnValue := mload(0x00)
ret := mload(0x40)
mstore(ret, returnSize)
returndatacopy(add(ret, 0x20), 0, returnSize)
// update free memory pointer
mstore(0x40, add(add(ret, 0x20), add(returnSize, 0x20)))
}
}
if (success && returnSize >= 0x20 && returnValue > 0) {
return (true, abi.decode(ret, (string)));
}
}
@>>> return (false, "");
}
}

Impact

When the token is bridged to starknet L2, the absence of a valid URI leads to the token lacking the necessary metadata.

Recommendations

Ensure that the baseURI function is implemented with the correct casing, following the ERC721 standard.
This will generate the correct bytes4 selector and allow the URI to be fetched properly.

Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-baseUri-selector-instead-of-baseURI

Likelyhood: Medium, no token using OZ version 2.X and 3.X will work. Impact: Low, Valid standard token won’t be mint with the URI but owner can use ERC721UriImpl function on the deployed token.

Support

FAQs

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