Skip to content

Commit

Permalink
Automatically merged updates to draft EIP(s) 1155 (ethereum#2049)
Browse files Browse the repository at this point in the history
Hi, I'm a bot! This change was automatically merged because:

 - It only modifies existing Draft or Last Call EIP(s)
 - The PR was approved or written by at least one author of each modified EIP
 - The build is passing
  • Loading branch information
AC0DEM0NK3Y authored and ilanolkies committed Nov 12, 2019
1 parent 1fb892a commit 755eeb6
Showing 1 changed file with 34 additions and 22 deletions.
56 changes: 34 additions & 22 deletions EIPS/eip-1155.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
eip: 1155
title: ERC-1155 Multi Token Standard
author: Witek Radomski <witek@enjin.com>, Andrew Cooke <ac0dem0nk3y@gmail.com>, Philippe Castonguay <pc@horizongames.net>, James Therien <james@turing-complete.com>, Eric Binet <eric@enjin.com>
author: Witek Radomski <witek@enjin.com>, Andrew Cooke <ac0dem0nk3y@gmail.com>, Philippe Castonguay <pc@horizongames.net>, James Therien <james@turing-complete.com>, Eric Binet <eric@enjin.com>, Ronan Sandford <wighawag@gmail.com>
type: Standards Track
category: ERC
status: Draft
Expand All @@ -13,7 +13,7 @@ requires: 165

## Simple Summary

A standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens, or other configurations (for example, semi-fungible tokens).
A standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens, or other configurations (e.g. semi-fungible tokens).

## Abstract

Expand Down Expand Up @@ -84,13 +84,13 @@ interface ERC1155 /* is ERC165 */ {
MUST revert if `_to` is the zero address.
MUST revert if balance of holder for token `_id` is lower than the `_value` sent.
MUST revert on any other error.
After the above conditions are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
MUST emit `TransferSingle` event on transfer success (see "Safe Transfer Rules" section of the standard).
MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
@param _from Source address
@param _to Target address
@param _id ID of the token type
@param _value Transfer amount
@param _data Additional data with no specified format, MUST be sent in call to `onERC1155Received` on `_to`
@param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;
Expand All @@ -100,15 +100,15 @@ interface ERC1155 /* is ERC165 */ {
MUST revert if `_to` is the zero address.
MUST revert if length of `_ids` is not the same as length of `_values`.
MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
MUST revert on any other error.
Transfers and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
MUST emit `TransferSingle` or `TransferBatch` event(s) on transfer success (see "Safe Transfer Rules" section of the standard).
MUST revert on any other error.
MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard).
Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
@param _from Source address
@param _to Target address
@param _ids IDs of each token type (order and length must match _values array)
@param _values Transfer amounts per token type (order and length must match _ids array)
@param _data Additional data with no specified format, MUST be sent in call to the `ERC1155TokenReceiver` hook(s) on `_to`
@param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;
Expand Down Expand Up @@ -193,13 +193,13 @@ interface ERC1155TokenReceiver {
This function MUST NOT consume more than 5,000 gas.
@return `bytes4(keccak256("isERC1155TokenReceiver()"))`
*/
function isERC1155TokenReceiver() external pure returns (bytes4);
function isERC1155TokenReceiver() external view returns (bytes4);
}
```

### Safe Transfer Rules

To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST operate with respect to the `ERC1155TokenReceiver`, a list of scenarios and rules follows.
To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST operate with respect to the `ERC1155TokenReceiver` hook functions, a list of scenarios and rules follows.

#### Scenarios

Expand All @@ -219,22 +219,30 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
**_Scenario#5 :_** The receiver implements the necessary `ERC1155TokenReceiver` interface function(s) but throws an error.
* The transfer MUST be reverted.

**_Scenario#6 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of one and only one balance change (eg. safeTransferFrom called).
**_Scenario#6 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of one and only one balance change (e.g. safeTransferFrom called).
* All the balances in the transfer MUST have been updated to match the senders intent before any hook is called on a recipient.
* All the transfer events for the transfer MUST have been emitted to reflect the balance changes before any hook is called on a recipient.
* One of `onERC1155Received` or `onERC1155BatchReceived` MUST be called on the recipient.
* The `onERC1155Received` hook SHOULD be called on the recipient contract and its rules followed.
- See "onERC1155Received rules" for further rules that MUST be followed.
* The `onERC1155BatchReceived` hook MAY be called on the recipient contract and its rules followed.
- See "onERC1155BatchReceived rules" for further rules that MUST be followed.

**_Scenario#7 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of more than one balance change (eg. safeBatchTransferFrom called).
**_Scenario#7 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of more than one balance change (e.g. safeBatchTransferFrom called).
* All the balances in the transfer MUST have been updated to match the senders intent before any hook is called on a recipient.
* All the transfer events for the transfer MUST have been emitted to reflect the balance changes before any hook is called on a recipient.
* `onERC1155Received` or `onERC1155BatchReceived` MUST be called on the recipient as many times as necessary such that every balance change for the recipient in the scenario is accounted for.
- The return magic value for every hook call MUST be checked and acted upon as per "onERC1155Received rules" and "onERC1155BatchReceived rules".
* The `onERC1155BatchReceived` hook SHOULD be called on the recipient contract and its rules followed.
- See "onERC1155BatchReceived rules" for further rules that MUST be followed.
* The `onERC1155Received` hook MAY be called on the recipient contract and its rules followed.
- See "onERC1155Received rules" for further rules that MUST be followed.

**_Scenario#8 :_** You are the creator of a contract that implements the `ERC1155TokenReceiver` interface and you forward the token(s) onto another address in one or both of `onERC1155Received` and `onERC1155BatchReceived`.
* Forwarding should be considered acceptance and then initiating a new `safeTransferFrom` or `safeBatchTransferFrom` in a new context.
- The prescribed keccak256 acceptance value magic for the receiver hook being called MUST be returned after forwarding is successful.
* The `_data` argument MAY be re-purposed for the new context.
* If forwarding unexpectedly fails the transaction MUST be reverted.

#### Rules

Expand All @@ -243,18 +251,18 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
* MUST revert if `_to` is the zero address.
* MUST revert if balance of holder for token `_id` is lower than the `_value` sent to the recipient.
* MUST revert on any other error.
* After the above conditions are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "onERC1155Received rules" section).
* MUST emit `TransferSingle` event on transfer success (see "TransferSingle and TransferBatch event rules" section).
* MUST emit the `TransferSingle` event to reflect the balance change (see "TransferSingle and TransferBatch event rules" section).
* After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "onERC1155Received rules" section).

**_safeBatchTransferFrom rules:_**
* Caller must be approved to manage all the tokens being transferred out of the `_from` account (see "Approval" section).
* MUST revert if `_to` is the zero address.
* MUST revert if length of `_ids` is not the same as length of `_values`.
* MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
* MUST revert on any other error.
* After the above conditions are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` or `onERC1155BatchReceived` on `_to` and act appropriately (see "`onERC1155Received` and onERC1155BatchReceived rules" section).
* MUST emit `TransferSingle` or `TransferBatch` event(s) on transfer success (see "TransferSingle and TransferBatch event rules" section).
* Transfers and events MUST occur in the array order they were submitted (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
* MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "TransferSingle and TransferBatch event rules" section).
* The balance changes and events MUST occur in the array order they were submitted (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
* After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` or `onERC1155BatchReceived` on `_to` and act appropriately (see "`onERC1155Received` and onERC1155BatchReceived rules" section).

**_TransferSingle and TransferBatch event rules:_**
* `TransferSingle` SHOULD be used to indicate a single balance transfer has occurred between a `_from` and `_to` pair.
Expand All @@ -278,14 +286,17 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
- When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
* The total value transferred from address 0x0 minus the total value transferred to 0x0 MAY be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the `TransferSingle` event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_value` of 0.
* All `TransferSingle` and `TransferBatch` events MUST be emitted to reflect all the balance changes that have occurred before any call(s) to `onERC1155Received` or `onERC1155BatchReceived`.
- To make sure event order is correct in the case of valid re-entry (e.g. if a receiver contract forwards tokens on receipt) state balance and events balance MUST match before calling an external contract.

**_onERC1155Received rules:_**
* The `_operator` argument MUST be the address of the account/contract that initiated the transfer (i.e. msg.sender).
* The `_from` argument MUST be the address of the holder whose balance is decreased.
- `_from` MUST be 0x0 for a mint.
* The `_id` argument MUST be the token type being transferred.
* The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.
* The `_data` argument MUST contain the extra information provided by the sender for the transfer.
* The `_data` argument MUST contain the unaltered information provided by the sender for the transfer.
- i.e. it MUST pass on the unaltered `_data` argument sent via the `safeTransferFrom` or `safeBatchTransferFrom` call for this transfer.
* The recipient contract MAY accept an increase of its balance by returning the acceptance magic value `bytes4(keccak256("accept_erc1155_tokens()"))`
- If the return value is `bytes4(keccak256("accept_erc1155_tokens()"))` the transfer MUST be completed or MUST revert if any other conditions are not met for success.
* The recipient contract MAY reject an increase of its balance by calling revert.
Expand All @@ -301,7 +312,8 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
- `_from` MUST be 0x0 for a mint.
* The `_ids` argument MUST be the list of tokens being transferred.
* The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in `_ids`) the holder balance is decreased by and match what the recipient balance is increased by.
* The `_data` argument MUST contain the information provided by the sender for a transfer.
* The `_data` argument MUST contain the unaltered information provided by the sender for the transfer.
- i.e. it MUST pass on the unaltered `_data` argument sent via the `safeTransferFrom` or `safeBatchTransferFrom` call for this transfer.
* The recipient contract MAY accept an increase of its balance by returning the acceptance magic value `bytes4(keccak256("accept_batch_erc1155_tokens()"))`
- If the return value is `bytes4(keccak256("accept_batch_erc1155_tokens()"))` the transfer MUST be completed or MUST revert if any other conditions are not met for success.
* The recipient contract MAY reject an increase of its balance by calling revert.
Expand All @@ -314,7 +326,7 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
**_isERC1155TokenReceiver rules:_**
* The implementation of `isERC1155TokenReceiver` function SHOULD be as follows:
```
function isERC1155TokenReceiver() external pure returns (bytes4) {
function isERC1155TokenReceiver() external view returns (bytes4) {
return 0x0d912442; // bytes4(keccak256("isERC1155TokenReceiver()"))
}
```
Expand Down

0 comments on commit 755eeb6

Please sign in to comment.