Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: low
Invalid

Invalid Metadata URI

Summary

The baseURI (which defines the metadata location for NFTs) can be set to an invalid or malformed URI via setBaseUri, leading to broken NFT metadata. The contract lacks validation to ensure baseURI is a properly formatted URI.

Vulnerability Details

string public baseURI = "ipfs://QmZzEbTnUWs5JDzrLKQ9yGk1kvszdnwdMaVw9vNgjCFLo2/";

The initial baseURI is valid (IPFS-compliant).

There is No guarantee future updates will follow the same format.

function setBaseUri(string memory _uri) external override onlyOwner {
baseURI = _uri; // No validation on _uri
emit BaseURIUpdated(_uri);
}

The owner can set baseURI to any arbitrary string (e.g., "", "invalid-uri", or a typo like "ipfs:/missing-slash").

All NFT metadata (accessed via tokenURI()) will point to invalid locations.

The ERC721 tokenURI() function constructs the metadata URL by appending the tokenId to baseURI as seen below:

function tokenURI(uint256 tokenId) public view override returns (string memory) {
_requireOwned(tokenId);
return bytes(baseURI).length > 0
? string(abi.encodePacked(baseURI, Strings.toString(tokenId)))
: "";
}

Example: If baseURI is set to "invalid", the metadata URL becomes "invalid1" (for tokenId = 1), which is unresolvable.

Marketplaces/wallets cannot display NFT artwork or attributes.

owner can accidentally set empty URI or typo in URI or non-standard URI.

Impact

Without URI validation, the contract’s metadata is vulnerable to human error or malicious actions by the owner, rendering NFTs unusable in practice.

Tools Used

Foundry

Recommendations

Add validation to setBaseUri to enforce URI standards:

function setBaseUri(string memory _uri) external override onlyOwner {
require(bytes(_uri).length > 0, "URI cannot be empty");
require(_isValidURI(_uri), "Invalid URI format");
baseURI = _uri;
emit BaseURIUpdated(_uri);
}
// Example validation
function _isValidURI(string memory _uri) internal pure returns (bool) {
return (bytes(_uri)[0] == 'i' && bytes(_uri)[1] == 'p' && bytes(_uri)[2] == 'f' && bytes(_uri)[3] == 's' && bytes(_uri)[4] == ':' && bytes(_uri)[5] == '/' && bytes(_uri)[6] == '/')
|| (bytes(_uri)[0] == 'h' && bytes(_uri)[1] == 't' && bytes(_uri)[2] == 't' && bytes(_uri)[3] == 'p' && bytes(_uri)[4] == 's' && bytes(_uri)[5] == ':' && bytes(_uri)[6] == '/' && bytes(_uri)[7] == '/');
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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