ERC-1155 is a multi-token standard that lets a single smart contract manage an unlimited number of token IDs, each with its own supply. Authored by Witek Radomski, Andrew Cooke, Philippe Castonguay, James Therien, Eric Binet, and Ronan Sandford of Enjin and collaborators, and proposed in June 2018 as EIP-1155, the standard now carries Final status on Ethereum's EIP track. Each token ID can be fungible (millions of identical copies), non-fungible (a single unique item), or semi-fungible (a numbered edition with a fixed cap).
This article explains the ERC-1155 interface, how batch operations save gas, and when ERC-1155 beats ERC-20 or ERC-721 for production deployments, including a side-by-side comparison across supply model, gas cost, and marketplace support. It also covers the ERC-1155 metadata extension and the safe-transfer hooks that prevent locked tokens.
What Is ERC-1155?
ERC-1155 was originally designed for game items: a single contract holds the entire item catalog of a game, with each item type assigned a token ID. A game with 10,000 sword variants and 10,000,000 gold pieces deploys once, not 10,001 times. The contract's balanceOf(address, id) returns how many of token id an address holds, replacing ERC-20's per-contract balanceOf(address) and ERC-721's per-token ownerOf(tokenId). OpenZeppelin's ERC-1155 guide notes the standard draws design ideas from ERC-20, ERC-721, and ERC-777 to be fungibility-agnostic in one contract.
Adoption has moved well beyond gaming. NFT marketplaces, edition platforms, and attendance-token issuers now run production ERC-1155 contracts across Ethereum, Polygon, and Arbitrum. OpenSea's overview of ERC-721 vs ERC-1155 documents the marketplace adoption pattern.
How ERC-1155 Works
The contract maintains a two-dimensional balance map: balances[id][address]. Standard operations:
balanceOf(address account, uint256 id), how many of tokenidthe account holds.balanceOfBatch(address[] accounts, uint256[] ids), batch read of multiple balances in one call.safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data), transfer some amount of one token ID.safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] amounts, bytes data), transfer multiple token IDs in one call.setApprovalForAll(address operator, bool approved), grant unlimited approval to a marketplace or game contract for all token IDs.
The single approval semantics matter: ERC-721 marketplaces require either per-token approval or a full-collection approval. ERC-1155 uses the full-collection model by default, which is why marketplaces like OpenSea and Rarible can list all of a user's ERC-1155 items after one approval transaction.
OpenZeppelin's reference example mints a game-items contract with five token IDs in one constructor call: GOLD and SILVER as high-supply fungible tokens, THOR'S HAMMER minted with a supply of exactly one as a non-fungible token, and SWORD and SHIELD as mid-supply semi-fungible items, all in a single deployment. The same example notes that ERC-1155 deliberately omits ERC-20's decimals field, since each token ID is either a whole-unit balance or a unique item and cannot be fractionally divided the way an ERC-20 balance can.
Batch Transfer Math
Batch transfer math means moving many token IDs in one call instead of one transaction per item. The EIP-1155 specification defines safeBatchTransferFrom for exactly this, sharing calldata and function-call overhead across every token ID in the batch.
An ERC-721 contract transferring 100 distinct tokens pays a full transaction base cost plus a storage write for each separate call. An ERC-1155 safeBatchTransferFrom with the same 100 tokens uses one calldata blob and a single function frame, which is why Enjin's original design rationale for the standard, documented in the EIP itself, cites batch operations as the primary gas-saving mechanism over deploying or calling per-token ERC-721 contracts.
The savings compound for in-game state changes: a guild trade moving 50 items between two players in one ERC-1155 batch call touches one transaction instead of 50 separate ERC-721 transfers. For high-frequency item economies, that difference is what makes the use case viable on a public chain.
Token ID Allocation Patterns
Token ID allocation is the scheme a contract uses to turn a single uint256 into a stable identifier for every item type it will ever mint, chosen once at design time because changing it later breaks every indexer and marketplace listing built against the old scheme. Production contracts use the full 256-bit space to encode metadata. Common patterns:
Sequential IDs, 1, 2, 3, ... for simple collections. Easy to reason about; no semantic meaning in the ID.
Class-and-instance encoding, upper 128 bits encode class (sword type), lower 128 bits encode instance (specific sword). Enjin's reference implementation uses this pattern.
Hash-derived IDs,
uint256(keccak256(abi.encode(type, attributes)))for deterministic IDs that can't collide.Type bits, top bit signals fungible vs non-fungible. Used by some games to separate inventory from currency in the same contract.
The choice interacts with gas cost too: class-and-instance and hash-derived schemes let off-chain indexers group related items without an on-chain registry lookup, at the cost of a less human-readable ID than sequential numbering.
ERC-1155 vs ERC-20 vs ERC-721: Decision Matrix
The standard to pick depends on whether items are interchangeable, how many distinct item types exist, and whether batch operations dominate usage. ERC-20 is single-asset and fungible-only, ERC-721 is one-token-per-contract-slot and unique-only, and ERC-1155 is the only one of the three that lets a single contract hold both fungible and non-fungible balances under different IDs.
Dimension | ERC-20 | ERC-721 | ERC-1155 | Sources |
Fungibility | Fungible only | Non-fungible only | Fungible, non-fungible, or semi-fungible, per ID, in one contract | |
Balance model |
|
|
| |
Batch transfer support | No native batch call | No native batch call; needs one call per token | Native | |
Created (EIP) | November 2015 | January 2018 | June 2018 | |
Typical use case | Currencies, governance tokens, stablecoins | 1-of-1 art, unique collectibles, domain names | Game inventories, edition drops, ticket batches, tokenized receipts |
Build with the matrix below for the decision itself:
Use ERC-20 when: every unit is identical and interchangeable, such as a currency, a governance token, or a stablecoin, and you never need to track distinct item types in the same contract.
Use ERC-721 when: every token is unique (1-of-1 art), per-token metadata varies wildly, you need named functions like
ownerOffor legibility, or your target marketplace doesn't index ERC-1155 cleanly.Use ERC-1155 when: you have many editions of one item, batch operations dominate (game inventories, ticket drops), your contract issues both fungible and non-fungible items, or gas is the binding constraint.
OpenSea, Blur, Magic Eden, and Rarible all index ERC-1155. Some smaller marketplaces and aggregators historically had weaker support; check before choosing.
Limits of ERC-1155
ERC-1155's main limits are the missing pieces every team ends up re-adding: no native decimals, no built-in royalty payout, and no per-ID enforcement of metadata format beyond a shared URI template.
Because a single contract holds every item type, per-ID metadata is only as reliable as the URI scheme the deploying team chooses, and OpenZeppelin's guide notes that metadata served this way is off-chain by default, so a project can change an item's stated attributes after mint unless it deliberately puts the metadata on-chain or pins it to IPFS. Royalties need the separate EIP-2981 extension (covered in the FAQ below), and teams that want ERC-721-style human-readable ownership functions like ownerOf don't get them natively, since ERC-1155 tracks balances by ID rather than a single owner per token.
Production Examples
ERC-1155 is the dominant standard in NFT subcategories where editions or batches matter.
Open Editions and Drops
Open editions use one ERC-1155 token ID and one supply counter for tens of thousands of identical mints. Zora's open-edition contracts, Manifold's editions, and Highlight's drops all use this pattern instead of minting one ERC-721 per copy.
This is what made large open editions economically viable on mainnet; minting each copy as a separate ERC-721 multiplies per-copy gas cost, since every mint is its own transaction rather than a shared batch call. Editions built on OpenZeppelin's ERC-1155 base contract get batch minting through _mintBatch out of the box.
Game Items
Game items are catalog entries in a single ERC-1155 contract rather than one contract per item type. Enjin Coin, Sandbox assets, and Gala Games items are ERC-1155, with token IDs partitioned across item types and inventory transfers using safeBatchTransferFrom.
This is the deployment pattern OpenZeppelin's own game-items reference contract demonstrates: currency (GOLD, SILVER), a unique item (THOR'S HAMMER), and mid-supply gear (SWORD, SHIELD) minted from one constructor, then transferred to players individually or in a single safeBatchTransferFrom call as inventories change hands. A studio shipping the ERC-721 equivalent would deploy a separate contract, or at minimum a separate mint function and approval flow, for every one of those item classes.
POAPs and Attendance Tokens
POAPs are proof-of-attendance tokens minted as ERC-1155-style collectibles, one token ID per event, one copy per attendee. POAP's own stats page reports more than 7.5 million POAPs minted by more than 46,000 issuers as of September 2026, per POAP's public stats page.
Tokenized Receipts
Tokenized receipts represent a claim on an underlying position or asset, and some protocols have evaluated ERC-1155 for this because one contract can track many receipt types by ID. Uniswap v4 docs describe the position-tracking model the protocol ultimately shipped with.
Safe Transfer Hooks and Locked Tokens
Safe transfer hooks are a receiver check that ERC-1155 borrowed from ERC-721: a contract receiving a token must implement onERC1155Received (or onERC1155BatchReceived for batches) and return a specific selector, or the transfer reverts.
This prevents tokens from being sent to contracts that can't handle them, a failure mode that has stranded tokens on standards without the check. OpenZeppelin's ERC-1155 documentation points to the Golem GNT contract, which holds hundreds of thousands of ERC-20 tokens sent by mistake with no way to recover them, as the pattern the receiver check is designed to prevent. The trade-off: a transfer to a contract that wasn't deployed with ERC-1155 awareness will revert even if a human user intended the action. Marketplaces and bridges that want to receive ERC-1155 tokens implement the hook, and OpenZeppelin ships a ready-made ERC1155Holder convenience contract for this.
Why ERC-1155 Matters for Onchain Programmability
Stablecoin orchestration platforms working with tokenized real-world assets, invoices, receipts, share certificates, increasingly rely on ERC-1155 because issuers want one contract per asset class rather than per individual asset. A treasury platform routing settlement against a tokenized invoice batch reads ERC-1155 balances directly. Read the stablecoin automation platforms overview for how multi-token primitives compose with treasury workflows. For the broader ERC catalog, see the essential ERC standards builders should know.
FAQ
Can ERC-1155 tokens be both fungible and non-fungible?
Yes. Each token ID has its own supply. A token ID with supply of 1 behaves as a non-fungible token. A token ID with supply of 1,000,000 behaves as a fungible token. A semi-fungible token has a fixed cap (e.g., 100 numbered editions). The same contract can hold all three at once.
Why is ERC-1155 cheaper than ERC-721 for batches?
ERC-1155 is cheaper for batches because safeBatchTransferFrom processes multiple token IDs in one transaction, sharing calldata and function-call overhead that ERC-721 pays separately for every single-token transfer.
Does ERC-1155 support royalties?
Not natively. Royalties on ERC-1155 (and ERC-721) come from the separate EIP-2981 NFT Royalty Standard, which any token contract can implement. Marketplaces query royaltyInfo(tokenId, salePrice) and route the royalty share to the recipient.
Can a wallet hold ERC-1155 tokens directly?
Externally-owned accounts (EOAs) hold ERC-1155 tokens without any special handling. Smart-contract wallets must implement onERC1155Received and onERC1155BatchReceived to accept transfers. Most production smart wallets (Safe, Coinbase Smart Wallet) implement these hooks by default.
Are ERC-1155 tokens supported across chains?
Yes. ERC-1155 is an EVM-level interface and works on any EVM-compatible chain (Ethereum, Polygon, Arbitrum, Base, Optimism, BNB Chain). Cross-chain transfers require a separate bridge or messaging layer; the standard itself does not address cross-chain coordination.

