Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
49fbbde
EDT-3069 Adding more clarity in transfer rules and other things, alte…
AC0DEM0NK3Y May 3, 2019
5a0fba2
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 3, 2019
73a3365
EDT-3069 id substitution example was not lowercase.
AC0DEM0NK3Y May 4, 2019
0557c37
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 4, 2019
ed9f0d1
EDT-3069 Updated the "Safe Transfer Rules" section to match feedback …
AC0DEM0NK3Y May 7, 2019
e331f58
EDT-3069 Some formatting changes to make it easier to digest/
AC0DEM0NK3Y May 7, 2019
3e2a176
EDT-3069 More formatting.
AC0DEM0NK3Y May 7, 2019
c9db596
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 7, 2019
3ba6d4f
EDT-3069 Move impl specific functions rules to the rules section.
AC0DEM0NK3Y May 7, 2019
b3f5675
EDT-3069 Better wording on impl specific api rules.
AC0DEM0NK3Y May 7, 2019
774c0ae
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 7, 2019
f745443
EDT-3069 Added in rules for TransferSingle and TransferBatch events s…
AC0DEM0NK3Y May 7, 2019
1f3a415
EDT-3069 EOA explanation.
AC0DEM0NK3Y May 8, 2019
54a4fa1
EDT-3069 Updated text after feedback.
AC0DEM0NK3Y May 9, 2019
2f16e0f
EDT-3069 Another update.
AC0DEM0NK3Y May 9, 2019
cdc350b
EDT- Minor wording changes, be consistent in how we name ERC numbers …
AC0DEM0NK3Y May 9, 2019
5083d1e
EDT-3069 Remove confusion on hook return vals and args.
AC0DEM0NK3Y May 9, 2019
5869a76
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 9, 2019
cbc7264
EDT-3069 Drop the "DRAFT" text from linked standards, so when we go f…
AC0DEM0NK3Y May 9, 2019
d5446f9
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 9, 2019
c62f69b
EDT-3069 Added safe and batch transferFrom rules to also be explicit …
AC0DEM0NK3Y May 9, 2019
dd6b5d7
EDT-3069 Another small change to match the rules.
AC0DEM0NK3Y May 9, 2019
4f36207
Changes to wording to clarify transfer rules.
JamesTherien May 10, 2019
b6f8829
Clarification for the _data parameter
JamesTherien May 10, 2019
67a42bc
Clarify rules of breaking down into multiple onReceived callbacks
JamesTherien May 10, 2019
8f0c356
Merge pull request #1 from JamesTherien/master
AC0DEM0NK3Y May 10, 2019
48cce31
EDT-3069 Alter the rejection logic back to normal for regular 115 ope…
AC0DEM0NK3Y May 10, 2019
f11b5c2
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 10, 2019
cd86485
EDT-3069 Small inconsistency and remove the ==<hex value> part from r…
AC0DEM0NK3Y May 11, 2019
206594c
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 11, 2019
d7b07bd
EDT-3069 Add in ERC-165 interface identifier info for the ERC1155Toke…
AC0DEM0NK3Y May 11, 2019
97fa9de
EDT-3069 Very minor change to text, remove odd grammar.
AC0DEM0NK3Y May 13, 2019
4f0378e
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 13, 2019
15a67ab
EDT-3069 Consistency change on the isERC1155TokenReceiver gas require…
AC0DEM0NK3Y May 13, 2019
65052c6
EDT-3069 Added wighawag as an author, alter isERC1155Receiver interfa…
AC0DEM0NK3Y May 18, 2019
8cb2756
EDT-3069 Minor grammar and consistency changes on use of "for example…
AC0DEM0NK3Y May 18, 2019
a560f91
EDT-3069 Change the recommended isERC1155TokenReceiver function to us…
AC0DEM0NK3Y May 18, 2019
2eedafb
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 18, 2019
cc3e971
EDT-3069 Small alteration to text by request.
AC0DEM0NK3Y May 21, 2019
c2a0f11
EDT-3069 Minor text consistency change.
AC0DEM0NK3Y May 22, 2019
4eaf2c7
EDT-3069 Fixed typo.
AC0DEM0NK3Y May 22, 2019
fb0e643
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 22, 2019
cc3a9d9
EDT-3069 Spelling.
AC0DEM0NK3Y May 22, 2019
caa8d27
EDT-3069 Minor formatting change.
AC0DEM0NK3Y May 22, 2019
d8b0d2f
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 22, 2019
8c96bfb
EDT-3069 Some small changes to wording for clarity.
AC0DEM0NK3Y May 24, 2019
282e0d0
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 24, 2019
50d401c
Revert magic_values to original byte4
PhABC May 24, 2019
d054f84
EDT-3069 Adding in scenario for non-standard api call and allow it to…
AC0DEM0NK3Y May 24, 2019
8d50450
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 25, 2019
eb36a93
Merge pull request #2 from PhABC/patch-7
AC0DEM0NK3Y May 25, 2019
ca3278b
EDT-3069 Minor consistency change.
AC0DEM0NK3Y May 25, 2019
cfae695
EDT-3069 Updated return value to latest after merge.
AC0DEM0NK3Y May 25, 2019
c21e799
EDT-3069 Consistency on calling "1155" "ERC-1155".
AC0DEM0NK3Y May 25, 2019
6dd5dc6
EDT-3069 Minor wording change.
AC0DEM0NK3Y May 25, 2019
343457a
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 25, 2019
91815a0
EDT-3069 More wording changes for clarification.
AC0DEM0NK3Y May 25, 2019
a3c61ba
EDT-3069 Small grammar change and capitalized API.
AC0DEM0NK3Y May 25, 2019
4ff6c62
EDT-3069 Change a MAY to SHOULD as a non-standard impl really should …
AC0DEM0NK3Y May 25, 2019
2a62512
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 25, 2019
4da1425
EDT-3069 Minor changes for grammar and consistency.
AC0DEM0NK3Y May 26, 2019
4aa3ac9
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 27, 2019
7a61926
EDT-3069 Slightly strong wording using SHOULD instead of a MAY in the…
AC0DEM0NK3Y May 27, 2019
a301bc6
EDT-3069 Solidity 0.5.9 is latest version (ref impl tested on this ve…
AC0DEM0NK3Y May 28, 2019
a9b6921
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 28, 2019
0ec4c57
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y May 28, 2019
16ad5b1
EDT-3069 Some alteration to the standard as requested along with a se…
AC0DEM0NK3Y Jun 1, 2019
eb1207b
EDT-3069 Minor grammar fix.
AC0DEM0NK3Y Jun 3, 2019
219d72a
EDT-3069 Add in mention that mint/burn is a custom transfer so follow…
AC0DEM0NK3Y Jun 4, 2019
e57d757
EDT-3069 Add in recommendation for wallets etc. to sort their batch t…
AC0DEM0NK3Y Jun 4, 2019
7800e85
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y Jun 4, 2019
8390de7
EDT-3069 More minor grammar and formatting fixes.
AC0DEM0NK3Y Jun 4, 2019
93cc841
DT-3069 Consistent use of MUST in uri event and function.
AC0DEM0NK3Y Jun 5, 2019
34df030
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y Jun 5, 2019
4f21e38
EDT-3069 Replace isERCTokenReceiver with usage of ERC165 supportsInte…
AC0DEM0NK3Y Jun 6, 2019
9de300a
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y Jun 7, 2019
463d6b2
URI event clarification
AC0DEM0NK3Y Jun 7, 2019
0a255c5
EDT-3069 Altered Metadata Extension rules to be clear about the ERC-1…
AC0DEM0NK3Y Jun 7, 2019
cb3cbfc
Merge branch 'master' of https://github.com/ethereum/EIPs
AC0DEM0NK3Y Jun 7, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
EDT-3069 Updated the "Safe Transfer Rules" section to match feedback …
…given in discussion thread. This introduces specific scenarios and rules to match.
  • Loading branch information
AC0DEM0NK3Y committed May 7, 2019
commit ed9f0d1fd8f45136f1b527fc4044176c48f51da0
111 changes: 71 additions & 40 deletions EIPS/eip-1155.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,60 +184,91 @@ interface ERC1155TokenReceiver {

### Safe Transfer Rules

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

**_Scenario:_** The recipient is not a contract.
* onERC1155Received and onERC1155BatchReceived MUST NOT be called on an EOA account.

**_Scenario:_** The transaction is not a mint/transfer of a token.
* onERC1155Received and onERC1155BatchReceived MUST NOT be called outside of a mint or transfer process.

##### When the recipient is a contract:

* The onERC1155Received hook MUST be called every time one and only one token type is transferred to an address in the transaction.
* The onERC1155Received hook MUST NOT be called when more than one token type is transferred to an address in the transaction.
* The onERC1155BatchReceived hook MUST be called when more than one token type is transferred to an address in the transaction with the entire list of what was transferred to it.
* The onERC1155BatchReceived hook MUST NOT be called when only one token type is transferred to an address in the transaction.

* If implementation specific functions are used to transfer 1155 tokens to a contract the appropriate hook MUST still be called with the same rules as if safeTransferFrom/safeBatchTransferFrom was used.
* If the destination/to contract does not implement the appropriate hook the transfer MUST be reverted with the one caveat below.
- If the tokens being sent are part of a hybrid implementation of another standard, that particular standard's rules on sending to a contract MAY now be followed instead. See "Compatibility with other standards" section.

* When calling either onERC1155Received or onERC1155BatchReceived:
- operator MUST be the address of the account/contract that initiated the transfer (i.e. msg.sender).
- from MUST be the address of the holder whose balance is decreased.
- to MUST be the address of the recipient whose balance is increased.
- from MUST be 0x0 for a mint.
- data MUST contain the extra information provided by the sender (if any) for a transfer.
- the hook MUST be called after all the balances in the transaction have been updated to match the senders intent.

* When calling onERC1155Received
- id MUST be the token type being transferred.
- value MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.
- If the return value is anything other than `bytes4(keccak256("accept_erc1155_tokens()"))` or `bytes4(keccack256("reject_erc1155_tokens()"))` the transaction MUST be reverted.

* When calling onERC1155BatchReceived
- ids MUST be the list of tokens being transferred.
- values MUST be the list of number of tokens (specified in ids) the holder balance is decreased by and match what the recipient balance is increased by.
- If the return value is anything other than `bytes4(keccak256("accept_batch_erc1155_tokens()"))` or `bytes4(keccack256("reject_erc1155_tokens()"))` the transaction MUST be reverted.

* The destination/to contract MAY accept an increase of its balance by returning the acceptance magic value `bytes4(keccak256("accept_erc1155_tokens()"))` for onERC1155Received or `bytes4(keccak256("accept_batch_erc1155_tokens()"))` for onERC1155BatchReceived.
- If such explicit acceptance happens the transfer MUST be completed, unless other conditions apply.
**_Scenario:_** The receiver does not implement the necessary ERC1155TokenReceiver interface function(s).
* The transfer MUST be reverted with the one caveat below.
- If the tokens being sent are part of a hybrid implementation of another standard, that particular standard's rules on sending to a contract MAY now be followed instead. See "Compatibility with other standards" section.

**_Scenario:_** The receiver implements the necessary ERC1155TokenReceiver interface function(s) but returns an unknown value.
* The transfer MUST be reverted.

**_Scenario:_** The receiver implements the necessary ERC1155TokenReceiver interface function(s) but throws an error.
* The transfer MUST be reverted.

**_Scenario:_** The receiver implements the ERC1155TokenReceiver interface and is the recipient of one and only one balance change in the transaction (eg. safeTransferFrom called).
* All the balances in the transaction MUST have been updated to match the senders intent before any hook is called on a recipient.
* The appropriate choice of either onERC1155Received or onERC1155BatchReceived MUST be called on the recipient.
* The onERC1155Received hook SHOULD be called on the recipient contract and its rules followed.
- If this hook is called it MUST NOT be called again on the recipient in this transaction.
- See "onERC1155Received common rules" for further rules that MUST be followed.
* The onERC1155BatchReceived hook MAY be called on the recipient contract and its rules followed
- See "onERC1155BatchReceived common rules" for further rules that MUST be followed.

**_Scenario:_** The receiver implements the ERC1155TokenReceiver interface and is the recipient of more than one balance change in the transaction (eg. safeBatchTransferFrom called).
* All the balances in the transaction MUST have been updated to match the senders intent before any hook is called on a recipient.
* The appropriate choice of either onERC1155Received or onERC1155BatchReceived MUST be called on the recipient.
* The onERC1155BatchReceived hook SHOULD be called on the recipient contract and its rules followed.
- If called the arguments MUST contain/list information on every balance change for the recipient (and only the recipient) in this transaction.
- See "onERC1155BatchReceived common rules" for further rules that MUST be followed.
* The onERC1155Received hook MAY be called on the recipient contract and its rules followed.
- If called it MUST be repeatedly called until information has been passed and return value checked for every balance change for the recipient (and only the recipient) in this transaction.
- See "onERC1155Received common rules" for further rules that MUST be followed.

**_Scenario:_** Implementation specific functions are used to transfer 1155 tokens to a contract.
* If implementation specific functions are used to transfer 1155 tokens to a contract the appropriate hook(s) MUST still be called with the same rules as if safeTransferFrom/safeBatchTransferFrom was used.
* The appropriate events MUST be correctly emitted as if safeTransferFrom/safeBatchTransferFrom was used.

##### onERC1155Received common rules:
* If this hook is called onERC1155BatchReceived MUST NOT also be called on the recipient in this transaction.
* 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 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 (if any) for a transfer.
* The destination/to 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, unless other conditions necessitate a revert.
* The destination/to contract MAY reject an increase of its balance by returning the rejection magic value `bytes4(keccack256("reject_erc1155_tokens()"))`.
- If such explicit rejection happens, the transfer MUST be reverted with the one caveat below.
- If the tokens being sent are part of a hybrid implementation of another standard, that particular standard's rules on sending to a contract MAY now be followed instead. See "Compatibility with other standards" section.

* A solidity example of the keccak256 generated constants for the return magic is:
- If the return value is `bytes4(keccak256("reject_erc1155_tokens()"))` the transaction MUST be reverted.
* If the return value is anything other than `bytes4(keccak256("accept_erc1155_tokens()"))` or `bytes4(keccack256("reject_erc1155_tokens()"))` the transaction MUST be reverted.

##### onERC1155BatchReceived common rules:
* If this hook is called onERC1155Received MUST NOT also be called on the recipient in this transaction.
* If this hook is called it MUST NOT be called again on the recipient in this transaction.
* 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 _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 extra information provided by the sender (if any) for a transfer.
* The destination/to 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, unless other conditions necessitate a revert.
* The destination/to contract MAY reject an increase of its balance by returning the rejection magic value `bytes4(keccack256("reject_erc1155_tokens()"))`.
- If the return value is `bytes4(keccak256("reject_erc1155_tokens()"))` the transaction MUST be reverted.
* If the return value is anything other than `bytes4(keccak256("accept_batch_erc1155_tokens()"))` or `bytes4(keccack256("reject_erc1155_tokens()"))` the transaction MUST be reverted.

##### A solidity example of the keccak256 generated constants for the return magic is:
- bytes4 constant public ERC1155_REJECTED = 0xafed434d; // keccak256("reject_erc1155_tokens()")
- bytes4 constant public ERC1155_ACCEPTED = 0x4dc21a2f; // keccak256("accept_erc1155_tokens()")
- bytes4 constant public ERC1155_BATCH_ACCEPTED = 0xac007889; // keccak256("accept_batch_erc1155_tokens()")

##### Compatibility with other standards

There have been requirements during the design discussions to have this standard be compatible with older standards when sending to contract addresses, specifically ERC721 at time of writing.
To cater for this there is some leeway with the rejection logic should a contract return `bytes4(keccack256("reject_erc1155_tokens()"))` from the call to onERC1155Received/onERC1155BatchReceived as detailed in the main "Safe Transfer Rules" section above.
In this case the hybrid implementation MAY now follow the secondary standard's rules when transferring token(s) to a contract address.
To cater for this there is some leeway with the rejection logic should a contract not implement the ERC1155TokenReceiver as per "Safe Transfer Rules" section above, specifically the scenario "The receiver does not implement the necessary ERC1155TokenReceiver interface function(s)".
In that particular scenario if the 1155 implementation is also a hybrid implementation of another token standard, it MAY now follow the secondary standard's rules when transferring token(s) to a contract address.

*__Note that a pure implementation of a single standard is recommended__* rather than a hybrid solution, but an example of a hybrid 1155+721 contract is linked in the references section under implementations.

Note however it is recommended that a hybrid solution NOT be followed and a pure implementation of a single standard is followed instead, as a hybrid solution is an unproven method to date.
An important consideration is that even if the tokens are sent with another standard's rules the *__1155 transfer events MUST still be emitted.__* This is so the balances can still be determined via events alone as per 1155 standard rules.

An example of a hybrid 1155+721 contract is linked in the references section under implementations.

### Metadata

Expand Down