{"id":"ERC-1046","name":"Token Metadata","status":"Final","chain":"both","category":{"id":"comprehension","name":"Comprehension & Display","description":"Making blockchain data readable to humans"},"journeyStages":[{"id":"asset-display","name":"Asset Discovery & Display","description":"Seeing tokens, NFTs, and balances"}],"uxImpact":"ERC-1046 lets a token publish a tokenURI for structured metadata. Supporting wallets can display names, descriptions and images from that document, with fallbacks when fields or the interface are missing. Contract-published metadata can still be false, stale or unsafe; it is not proof that a token is authentic.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-1046","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"ERC-1046","summary":"ERC-1046 lets a token publish a tokenURI for structured metadata. Supporting wallets can display names, descriptions and images from that document, with fallbacks when fields or the interface are missing. Contract-published metadata can still be false, stale or unsafe; it is not proof that a token is authentic.","applicability":{"whenToUse":["A token exposes tokenURI and your client can safely fetch and parse the metadata.","Your display includes missing-field, stale-resource and independent identity-check states."],"whenToAvoid":["Fetching the URI would violate your request or privacy policy.","You would label the token authentic solely because its contract published the metadata."]},"designerTakeaways":["Show when metadata comes from the token contract, while keeping token identity checks separate.","Render optional image, images, and icons fields only when the client supports them.","Provide a safe fallback for missing, stale, malformed, or untrusted metadata."],"problemsSolved":[{"problem":"Token info depends on centralized token lists","oldWay":"Wallet fetches name/icon from Coingecko or static lists","newWay":"Token contract points to contract-published metadata","impact":"high"},{"problem":"Fake tokens can impersonate real ones","oldWay":"Scam token shows same name/symbol, users confused","newWay":"The URI comes from the token contract; token identity still needs independent checks","impact":"high"},{"problem":"No standard way to include token icons","oldWay":"Icon lookup varies by wallet, often missing","newWay":"Optional image, images and icons metadata fields","impact":"medium"},{"problem":"Token descriptions aren't available on-chain","oldWay":"Users must search externally to understand token","newWay":"A compatible client may show a description from fetched metadata, subject to trust and availability checks","impact":"medium"},{"problem":"Updating token info requires list maintainer action","oldWay":"Submit PR to token list, wait for merge","newWay":"Project updates their metadata URI directly","impact":"medium"}],"uxPatterns":[{"name":"Rich Token Display","description":"Show complete token info from metadata","userFlow":["User taps on token in wallet","Wallet fetches tokenURI from contract","Parses JSON metadata","Displays rich token information","Label the URI as published by the contract, without implying that its contents are verified"]},{"name":"Token Discovery with Metadata","description":"Add new tokens with auto-fetched info","userFlow":["User pastes token address","Wallet checks for tokenURI function","Fetches and parses metadata","Show the metadata source and any independent identity checks, or an unknown status","User adds token with confidence"]},{"name":"Scam Token Warning","description":"Detect potential impersonation attempts","userFlow":["Token appears in wallet/dApp","Metadata claims to be known token","Contract address doesn't match","Clear warning displayed","Options to block or report"]},{"name":"Balance Display with Branding","description":"Token list with proper logos and info","userFlow":["Wallet loads token balances","Fetches metadata for each token","Displays logo from metadata or placeholder","Shows verification status per token","Users can identify trusted vs unknown"]}],"uiComponents":[{"name":"TokenMetadataFetcher","description":"Fetch and parse token metadata from URI","states":["idle","fetching","parsed","error","no-metadata"],"props":["contractAddress","onMetadata","fallback"]},{"name":"TokenLogo","description":"Display token icon from metadata","states":["loading","loaded","fallback","error"],"props":["uri","symbol","size"]},{"name":"MetadataVerificationBadge","description":"Show metadata source and trust level","states":["verified","from-contract","from-list","unknown","suspicious"],"props":["source","contractAddress"]},{"name":"TokenDescription","description":"Expandable token description display","states":["collapsed","expanded","no-description"],"props":["description","maxLength"]}],"antiPatterns":[{"pattern":"Trusting metadata without verification","why":"Scam tokens can claim any name/logo","instead":"Cross-reference with known contracts, show verification status","severity":"critical"},{"pattern":"Showing unknown tokens same as verified ones","why":"Users can't distinguish trusted from suspicious","instead":"Visual distinction: verified badge, warning for unknown","severity":"critical"},{"pattern":"Not caching metadata","why":"Slow/expensive to fetch metadata on every view","instead":"Cache with reasonable TTL, refresh periodically","severity":"high"},{"pattern":"Hiding token contract address","why":"The address identifies the contract but does not make its metadata truthful","instead":"Show the contract address with an easy copy action","severity":"medium"},{"pattern":"Not handling missing metadata gracefully","why":"Many tokens won't have ERC-1046 metadata","instead":"Graceful fallback to on-chain name/symbol or \"Unknown\"","severity":"medium"}],"keyTakeaways":["Treat tokenURI metadata as untrusted contract-published content.","Parse interop and support missing optional fields, including image arrays.","Use independent identity checks before showing a verified badge.","Show the address, source, refresh state and a fallback when fetching fails."],"technicalNotes":"ERC-1046 tokenURI() points to a metadata document. ERC-20 metadata includes the required interop object; name, symbol, decimals, description, image, images and icons are optional under the schema. images and icons are arrays. external_url and arbitrary social fields are not required ERC-1046 fields. Parse the declared schema, treat fetched data as untrusted, restrict URI fetching to avoid SSRF, and handle missing or stale resources. A contract-published URI establishes provenance, not independent token authenticity. Cache with refresh and fallback behavior.","lastUpdated":"2026-09-18","lastReviewed":"2026-09-18","specConstraints":[{"id":"metadata-fields-optional","constraint":"ERC-1046 metadata fields are optional.","appliesTo":"application","normativity":"normative","specQuote":"* All fields MUST be optional.","specSection":"Specification — Interoperability Metadata","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#interoperability-metadata","designImplication":"Handle missing metadata without treating it as a broken token. Use explicit unknown states instead of empty labels that look final."},{"id":"metadata-json-schema","constraint":"Resolved token metadata must be JSON conforming to the relevant ERC-1046 metadata schema.","appliesTo":"application","normativity":"normative","specQuote":"/// @dev        The resolved data MUST be in JSON format and support ERC-1046's ERC-20 Token Metadata Schema","specSection":"Specification — ERC-20 Extension — ERC-20 Interface Extension","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#erc-20-interface-extension","designImplication":"Validate and render metadata according to the declared token standard. Keep malformed or unavailable metadata visibly separate from a valid empty value."},{"id":"metadata-matches-token","constraint":"Metadata name, symbol, and decimals must match the corresponding ERC-20 values when those values are present.","appliesTo":"application","normativity":"normative","specQuote":"* If the `name()` function is present in the ERC-20 token and returns a nonempty string, these MUST be the same value.","specSection":"Specification — ERC-20 Extension — ERC-20 Token Metadata Schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#erc-20-token-metadata-schema","designImplication":"Use the contract and metadata values consistently in the token view and show a mismatch state when they disagree."},{"id":"metadata-image-shape","constraint":"Metadata images use a square aspect ratio and transparent background, with the specified bitmap dimensions when applicable.","appliesTo":"application","normativity":"normative","specQuote":"* If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels, and MUST have a height equal to its width","specSection":"Specification — ERC-20 Extension — ERC-20 Token Metadata Schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#erc-20-token-metadata-schema","designImplication":"Reserve a square transparent image treatment and preserve an explicit fallback when the asset does not meet the suggested dimensions."},{"id":"metadata-uri-compatibility","constraint":"The extension is optional and backward compatible with ERC-20, ERC-721, and ERC-1155 metadata interfaces.","appliesTo":"application","normativity":"backwards-compatibility","specQuote":"## Backwards Compatibility\n\nThis EIP is fully backwards compatible as its implementation simply extends the functionality of ERC-20 tokens and is optional. Additionally, it makes backward compatible recommendations for ERC-721 and ERC-1155 tokens.","specSection":"Backwards Compatibility","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#backwards-compatibility","designImplication":"Keep existing token metadata paths working and treat ERC-1046 metadata as an available extension, not a universal guarantee."},{"id":"metadata-uri-ssrf","constraint":"Wallets should sanitize metadata URIs by whitelisting schemes and ports to reduce SSRF risk.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"### Server-Side Request Forgery (SSRF)\n\nWallets should be careful about making arbitrary requests to URLs. As such, it is recommended for wallets to sanitize the URI by whitelisting specific schemes and ports. A vulnerable wallet could be tricked into, for example, modifying data on a locally-hosted redis database.","specSection":"Security Considerations — Server-Side Request Forgery (SSRF)","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#server-side-request-forgery-ssrf","designImplication":"Do not fetch arbitrary metadata URLs with privileged wallet access. Show unavailable or blocked metadata without weakening the wallet’s network policy."},{"id":"metadata-standard-indicators","constraint":"Setting the corresponding interoperability flag to true SHOULD tell wallets to treat the address as the indicated ERC-20, ERC-721, or ERC-1155 token standard.","appliesTo":"wallet","normativity":"normative","specSection":"Specification > Interoperability Metadata","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#interoperability-metadata","designImplication":"Use a true standard indicator to select the matching parser and labels; otherwise retain an unknown or generic-token state rather than guessing.","specQuote":"* Setting this to true indicates to wallets that the address should be treated as an ERC-20 token."},{"id":"metadata-image-aspect-ratio","constraint":"Metadata images SHOULD use an aspect ratio between 1.91:1 and 4:5 inclusive.","appliesTo":"application","normativity":"normative","specSection":"Specification > ERC-20 Extension > ERC-20 Token Metadata Schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#erc-20-token-metadata-schema","designImplication":"Preserve the recommended ratio in previews where possible and disclose crop or fallback behavior when an image does not fit.","specQuote":"* The image SHOULD have an aspect ratio between 1.91:1 and 4:5 inclusive."},{"id":"erc721-metadata-extension","constraint":"Contracts that implement ERC-721 and use its token metadata URI SHOULD use the described metadata extension.","appliesTo":"account-implementation","normativity":"normative","specSection":"Specification > ERC-721 Extension > Extension to the ERC-721 Metadata Schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#extension-to-the-erc-721-metadata-schema","designImplication":"Feature-detect the extension and parse the standard fields when present, with explicit fallback for contracts that omit it.","specQuote":"Contracts that implement ERC-721 and use its token metadata URI SHOULD to use the following TypeScript extension to the metadata URI:"},{"id":"erc1155-metadata-interface","constraint":"ERC-1155-compliant contracts using the metadata extension SHOULD implement the described Solidity interface.","appliesTo":"account-implementation","normativity":"normative","specSection":"Specification > ERC-1155 Extension > ERC-1155 Interface Extension","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#erc-1155-interface-extension","designImplication":"Detect the interface before relying on ERC-1155-specific metadata fields.","specQuote":"[ERC-1155](./eip-1155.md)-compliant contracts using the metadata extension SHOULD implement the following Solidity interface:"},{"id":"erc1155-metadata-schema","constraint":"ERC-1155 metadata URI users are RECOMMENDED to use the described extension, and interface implementers MUST use the corresponding TypeScript extension.","appliesTo":"account-implementation","normativity":"normative","specSection":"Specification > ERC-1155 Extension > Extension to the ERC-1155 Metadata Schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#extension-to-the-erc-1155-metadata-schema","designImplication":"Keep RECOMMENDED metadata parsing separate from the MUST condition for interface implementers and show an explicit unsupported-schema fallback.","specQuote":"Contracts that implement ERC-1155 and use its token metadata URI are RECOMMENDED to use the following extension to the metadata URI. Contracts that implement the interface described in the ERC-1155 Interface Extension section MUST use the following TypeScript extension:"},{"id":"metadata-field-duplication","constraint":"When the metadata URI is authoritative, compliant contracts are RECOMMENDED not to duplicate name, symbol, or decimals; when ERC-20 decimals is 18, including decimals in metadata is NOT RECOMMENDED.","appliesTo":"application","normativity":"normative","specSection":"Specification > Miscellaneous Recommendations","specUrl":"https://ercs.ethereum.org/ERCS/erc-1046#miscellaneous-recommendations","designImplication":"Define metadata-versus-contract fallback precedence, and do not treat omitted decimals as a missing value when the standard's 18-decimal convention applies.","specQuote":"To save gas, it is RECOMMENDED for compliant contracts not to implement the `name()`, `symbol()`, or `decimals()` functions, and instead to only include them in the metadata URI. Additionally, for ERC-20 tokens, if the decimals is `18`, then it is NOT RECOMMENDED to include the `decimals` field in the metadata."}],"sources":[{"label":"ERC-1046 official specification","url":"https://ercs.ethereum.org/ERCS/erc-1046","type":"official-spec"}]},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-1046","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-1046","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-1046","markdown":"https://www.eipsfordesigners.com/standards/ERC-1046/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-1046/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-1046","official":"https://ercs.ethereum.org/ERCS/erc-1046","discussion":"https://ethereum-magicians.org/search?q=ERC-1046"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}