ERC-5679 Token mint and burn extension standard (Token Minting and Burning)
Final · Tokens · created 2022-09-17
An extension that adds mint and burn functions to EIP-20, EIP-721, and EIP-1155 tokens in a uniform way. It completes the basic token lifecycle of creating and destroying tokens with standard functions.
Why it is needed
The token standards EIP-20, EIP-721, and EIP-1155 define how to send and receive tokens, but they do not separately define how to create or destroy tokens. As a result, some EIP-721 and EIP-1155 implementations have handled minting and burning by borrowing the transfer function or similar methods. However, minting and burning change a token's total supply, and the access control rules that decide who can do them usually differ from those for transfers. Mixing minting and burning into the transfer function makes implementations more complex and makes mistakes in permission settings more likely. Also, without a consistent method, the basic token lifecycle of creating, moving, and destroying remains incomplete as a standard. This standard aims to simplify implementations and reduce security errors by defining dedicated mint and burn functions suited to each of the three token standards.
What to implement
function mint(address _to, uint256 _amount, bytes calldata _data) external;: Creates _amount new EIP-20 tokens and gives them to _to. It emits an event as if transferred from 0x0 to _to and increases total supply.function burn(address _from, uint256 _amount, bytes calldata _data) external;: Destroys _amount of EIP-20 tokens from _from. It emits an event as if transferred to 0x0 and decreases total supply.function safeMint(address _to, uint256 _id, bytes calldata _data) external;: Creates a new EIP-721 token _id and gives it to _to. It applies the same recipient restrictions as safeTransferFrom.function burn(address _from, uint256 _id, bytes calldata _data) external;: Destroys EIP-721 token _id from _from. It emits an event as if transferred to 0x0 and decreases total supply.function safeMint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;: Creates _amount of a new EIP-1155 token _id and gives them to _to. It applies the same recipient restrictions as safeTransferFrom.function safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;: Mints multiple types of EIP-1155 tokens in one call according to ids and amounts and gives them to to.function burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata _data) external;: Destroys _amount of EIP-1155 token _id from _from. In the original declaration, _data is an array type, bytes[].function burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata _data) external;: Destroys multiple types of EIP-1155 tokens from _from in one call according to ids and amounts.
In depth
Scope: a different interface for each of the three standards
This standard extends EIP-20, EIP-721, and EIP-1155 tokens. A contract that follows any of these standards and adopts this extension MUST implement the interface that corresponds to that standard. The EIP-165 identifier of IERC5679Ext20 for EIP-20 is 0xd0017968, IERC5679Ext721 for EIP-721 is 0xcce39764, and IERC5679Ext1155 for EIP-1155 is 0xf4cedd5a. Because the function signatures differ between the interfaces, the identifiers are kept separate instead of being merged into one. Clients are RECOMMENDED to implement these identifiers through EIP-165. EIP-777 handles minting and burning on its own, so it was excluded from the extension.
EIP-20 extension: mint and burn
An EIP-20 token implements mint(address _to, uint256 _amount, bytes calldata _data) and burn(address _from, uint256 _amount, bytes calldata _data). The quantity is expressed as a single _amount, as in EIP-20, and there is no token ID. _data is a byte sequence passed along with the call, and the source does not specify how it is used. Unlike EIP-721 and EIP-1155, the minting function is named mint rather than safeMint, and there are no batch functions. When minting, the token MUST emit a transfer event as if _amount were transferred from 0x0 to _to, and MUST increase the total supply. When burning, it MUST emit an event as if the tokens were transferred to 0x0, and MUST decrease the total supply.
EIP-721 extension: safeMint and burn
An EIP-721 token implements safeMint(address _to, uint256 _id, bytes calldata _data) and burn(address _from, uint256 _id, bytes calldata _data). It takes a single token ID, _id, instead of a quantity. This follows the way EIP-721 identifies a token by its _id. The source also considered unifying the three interfaces so that they always carry an _amount, as EIP-1155 does, but decided to keep the _id and _amount representations that each token standard originally uses. EIP-721 has no batch functions such as safeMintBatch or burnBatch. This decision also follows the convention of EIP-721.
EIP-1155 extension: single and batch functions
An EIP-1155 token implements four functions. safeMint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) mints one type of token. safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) mints several types at once. burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata _data) burns one type, and burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata _data) burns several types at once. Taking both a token ID and a quantity follows the _id and _amount representation of EIP-1155, and the batch functions are also a result of following the EIP-1155 convention. In the source declarations, the parameters of safeMintBatch are written without underscores as to, ids, amounts, and data, and the _data of the single burn is an array type bytes[] rather than bytes. Implementations must follow the types in the source declarations exactly.
Events and total supply on minting
When a token is minted, a transfer event MUST be emitted. For EIP-20 and EIP-1155 it is recorded as if _amount tokens, and for EIP-721 and EIP-1155 as if the token with ID _id, were transferred from the 0x0 address to the receiving address that _to points to. The total supply MUST also increase by the same amount. This standard does not create a new event and uses the transfer events that EIP-20, EIP-721, and EIP-1155 already require. This choice maximizes compatibility.
Events and total supply on burning
A transfer event MUST also be emitted when a token is burned. This time it is recorded as if _amount tokens (EIP-20, EIP-1155) or the token with ID _id (EIP-721, EIP-1155) were transferred from the holding address to the 0x0 address, and the total supply MUST decrease by the same amount. Item 5 of the source specification describes the sender as the receiving address that _to points to, but in the burn and burnBatch function declarations the parameter name for the address that loses the tokens is _from. As with minting, no new event is defined, and the existing transfer event of each token standard is used.
Recipient restrictions on safeMint
The safeMint of EIP-721 and EIP-1155 MUST apply the same recipient restrictions that the safeTransferFrom of each standard defines. In EIP-721 and EIP-1155, safeTransferFrom includes a step that checks whether the recipient can accept the token when the recipient is a contract. Minting also means a token entering a new address, so this rule ensures that the safety check used in transfers is not skipped for minting. The safeMintBatch of EIP-1155 also has safe in its name and belongs to the same interface.
Status, dependencies, compatibility
This proposal is in Final status and was created on September 17, 2022. It requires EIP-20, EIP-165, EIP-721, and EIP-1155. The source states that this extension is designed to be compatible with each of EIP-20, EIP-721, and EIP-1155. Not defining new events and instead requiring the existing transfer event of each standard, keeping the representation of quantities and IDs as each standard defines it, and placing the batch functions only in EIP-1155 are all choices that prioritize compatibility with the existing standards. Support is checked through the EIP-165 identifier of each interface.
Things to watch out for
- Strictly limit minting authority: The design must be careful about which roles are given the authority to mint new tokens. If this is not done, unauthorized minting can occur and the total supply can be inflated.
- Design burning authority separately: Usually only the current token holder (role 1) or a role with special authority (role 2) can burn. It is common to allow burning by either one, or by agreement of both. The source recognizes that some use cases may require a third role to burn and does not set a strong restriction, so implementers must design the restrictions carefully on their own.
- Reliance on a sound underlying ledger: The safety of this standard depends on whether the ledger logic that the token implementation uses to record balances and total supply is sound. Before adding mint and burn functions, you must verify that the underlying token implementation itself is safe.