diff --git a/EIPS/eip-777.md b/EIPS/eip-777.md index 3fbbe635..42924448 100644 --- a/EIPS/eip-777.md +++ b/EIPS/eip-777.md @@ -31,7 +31,7 @@ This standard tries to improve the widely used [ERC20] token standard. The main 3. Both contracts and regular addresses can control and reject which token they receive by registering a `tokensReceived` hook. (Rejection is done by `revert`ing in the hook function.) 4. The `tokensReceived` hook allows to send tokens to a contract and notify it in a single transaction, unlike [ERC20] which require a double call (`approve`/`transferFrom`) to achieve this. 5. The token holder can "authorize" and "revoke" operators which can send tokens on their behalf. These operators are intended to be verified contracts such as an exchange, a cheque processor or an automatic charging system. -6. Every token transaction contains a `data` bytes field and a similar `operatorData` to be used freely to pass data to the recipient. +6. Every token transaction contains `data` and `operatorData` bytes fields to be used freely to pass data from the token holder and the operator, respectively. 7. It is backward compatible with wallets that do not contain the `tokensReceived` hook function by deploying a proxy contract implementing the `tokensReceived` hook for the wallet. ## Specification @@ -291,7 +291,7 @@ When an *operator* sends an `amount` of tokens from a *token holder* to a *recip - The balance of the *recipient* MUST be increased by the `amount`. - The balance of the *token holder* MUST be greater or equal to the `amount`—such that its resulting balance is greater or equal to zero (`0`) after the send. - The token contract MUST emit a `Sent` event with the correct values as defined in the [`Sent` Event][sent]. -- The *operator* MAY communicate any information in the `operatorData`. +- The *operator* MAY include information in the `operatorData`. - The token contract MUST call the `tokensToSend` hook of the *token holder* if the *token holder* registers an `ERC777TokensSender` implementation via [ERC820]. - The token contract MUST call the `tokensReceived` hook of the *recipient* if the *recipient* registers an `ERC777TokensRecipient` implementation via [ERC820]. - The `data` and `operatorData` MUST be immutable during the entire send process—hence the same `data` and `operatorData` MUST be used to call both hooks and emit the `Sent` event. @@ -322,7 +322,14 @@ The token contract MAY send tokens from many *token holders*, to many *recipient - The token contract MUST call the `tokensReceived` hook *after* updating the state. I.e., `tokensToSend` MUST be called first, then the balances MUST be updated to reflect the send, and finally `tokensReceived` MUST be called *afterward*. Thus a `balanceOf` call within `tokensToSend` returns the balance of the address *before* the send and a `balanceOf` call within `tokensReceived` returns the balance of the address *after* the send. -*NOTE*: The `data` field contains extra information intended for, and defined by the recipient— similar to the data field in a regular ether send transaction. Typically, `data` is used to describe the intent behind the send. The `operatorData` MUST only be provided by the *operator*. It is intended more for logging purposes and particular cases. (Examples include payment references, cheque numbers, countersignatures and more.) In most of the cases the recipient would ignore the `operatorData`, or at most, it would log the `operatorData`. +*NOTE*: The `data` field contains information provided by the token holder—similar +to the data field in a regular ether send transaction. +The `tokensToSend()` hook, the `tokensReceived()`, or both +MAY use the information to decide if they wish to reject the transaction. + +*NOTE*: The `operatorData` field is analogous to the `data` field except it SHALL be provided by the *operator*. + +Typically, `data` is used to describe the intent behind the send. The `operatorData` MUST only be provided by the *operator*. It is intended more for logging purposes and particular cases. (Examples include payment references, cheque numbers, countersignatures and more.) In most of the cases the recipient would ignore the `operatorData`, or at most, it would log the `operatorData`. **`Sent` event** @@ -339,8 +346,8 @@ Indicate a send of `amount` of tokens from the `from` address to the `to` addres > `from`: Token holder. > `to`: Token recipient. > `amount`: Number of tokens to send. -> `data`: Information attached to the send, and intended for the recipient (`to`). -> `operatorData`: Information attached to the send by the `operator`. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. The `send` and `operatorSend` functions described below MUST be implemented to send tokens. Token contracts MAY implement other functions to send tokens. @@ -360,7 +367,7 @@ The *operator* and the *token holder* MUST both be the `msg.sender`. > **parameters** > `to`: Token recipient. > `amount`: Number of tokens to send. -> `data`: Information attached to the send, and intended for the recipient (`to`). +> `data`: Information provided by the *token holder*. **`operatorSend` function** @@ -380,8 +387,8 @@ The *operator* MUST be `msg.sender`. The value of `from` MAY be `0x0`, then the > `from`: Token holder (or `0x0` to set `from` to `msg.sender`). > `to`: Token recipient. > `amount`: Number of tokens to send. -> `data`: Information attached to the send, and intended for the recipient (`to`). -> `operatorData`: Information attached to the send by the `operator`. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. #### **Minting Tokens** @@ -396,6 +403,7 @@ Nonetheless, the rules below MUST be respected when minting for a *recipient*: - The token contract MUST emit a `Minted` event with the correct values as defined in the [`Minted` Event][minted]. - The token contract MUST call the `tokensReceived` hook of the *recipient* if the *recipient* registers an `ERC777TokensRecipient` implementation via [ERC820]. - The `data` and `operatorData` MUST be immutable during the entire mint process—hence the same `data` and `operatorData` MUST be used to call the `tokensReceived` hook and emit the `Minted` event. +- The `data` field MUST be empty. The token contract MUST `revert` when minting in any of the following cases: @@ -418,7 +426,10 @@ The token contract MAY mint tokens for multiple *recipients* at once. In this ca *NOTE*: Minting an amount of zero (`0`) tokens is valid and MUST be treated as a regular mint. -*NOTE*: The `data` field contains extra information intended for, and defined by the recipient— similar to the data field in a regular ether send transaction. Typically, `data` is used to describe the intent behind the mint. The `operatorData` MUST only be provided by the *operator*. It is intended more for logging purposes and particular cases. (Examples include payment references, cheque numbers, countersignatures and more.) In most of the cases the recipient would ignore the `operatorData`, or at most, it would log the `operatorData`. +*NOTE*: The `operatorData` field contains information provided by the *operator*—similar +to the data field in a regular ether send transaction. +The `tokensReceived()` hooks MAY use the information to decide if it wish to reject the transaction. + **`Minted` event** @@ -434,8 +445,8 @@ Indicate the minting of `amount` of tokens to the `to` address by the `operator` > `operator`: Address which triggered the mint. > `to`: Token recipient. > `amount`: Number of tokens minted. -> `data`: Information attached to the minting, and intended for the recipient (`to`). -> `operatorData`: Information attached to the minting by the `operator`. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. #### **Burning Tokens** @@ -450,7 +461,6 @@ The rules below MUST be respected when burning the tokens of a *token holder*: - The token contract MUST emit a `Burned` event with the correct values as defined in the [`Burned` Event][burned]. - The token contract MUST call the `tokensToSend` hook of the *token holder* if the *token holder* registers an `ERC777TokensSender` implementation via [ERC820]. - The `operatorData` MUST be immutable during the entire burn process—hence the same `operatorData` MUST be used to call the `tokensToSend` hook and emit the `Burned` event. -- The `data` field of the `tokensToSend` hook MUST be empty. The token contract MUST `revert` when burning in any of the following cases: @@ -491,8 +501,9 @@ Indicate the burning of `amount` of tokens from the `from` address by the `opera > **parameters** > `operator`: Address which triggered the burn. > `from`: Token holder whose tokens are burned. -> `amount`: Number of tokens burned. -> `operatorData`: Information attached to the burn by the `operator`. +> `amount`: Number of tokens burned. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. The `burn` and `operatorBurn` functions described below MUST be implemented to burn tokens. Token contracts MAY implement other functions to burn tokens. @@ -526,7 +537,8 @@ The *operator* MUST be `msg.sender`. The value of `from` MAY be `0x0`, then the > **parameters** > `from`: Token holder whose tokens will be burned (or `0x0` to set `from` to `msg.sender`). > `amount`: Number of tokens to burn. -> `operatorData`: Information attached to the burn by the *operator*. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. *NOTE*: The *operator* MAY pass any information via `operatorData`. The `operatorData` MUST only be provided by the *operator*. @@ -566,8 +578,8 @@ Notify a send or burn (if `to` is `0x0`) of `amount` tokens from the `from` addr > `from`: *token holder*. > `to`: *token recipient* for a send and `0x` for a burn. > `amount`: Number of tokens the *token holder* balance is decreased by. -> `data`: Extra information provided by the *token holder*. -> `operatorData`: Extra information provided by the address which triggered the balance decrease. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. The following rules apply when calling the `tokensToSend` hook: @@ -579,7 +591,6 @@ The following rules apply when calling the `tokensToSend` hook: - `to` MUST be `0x0` for a burn. - `amount` MUST be the number of tokens the *token holder* balance is decreased by. - `data` MUST contain the extra information provided by the *token holder* (if any) for a send. -- `data` MUST be empty for a burn. - `operatorData` MUST contain the extra information provided by the address which triggered the decrease of the balance (if any). - The *token holder* MAY block a decrease of its balance by `revert`ing. (I.e., reject the withdrawal of tokens from its account.) @@ -629,8 +640,8 @@ Notify a send or mint (if `from` is `0x0`) of `amount` tokens from the `from` ad > `from`: *token holder* for a send and `0x` for a mint. > `to`: *token recipient*. > `amount`: Number of tokens the *recipient* balance is increased by. -> `data`: Extra information provided by the *token holder* for a send and nothing (empty bytes) for a mint. -> `operatorData`: Extra information provided by the address which triggered the balance increase. +> `data`: Information provided by the *token holder*. +> `operatorData`: Information provided by the *operator*. The following rules apply when calling the `tokensReceived` hook: