From 4eb6eab9cb109ca53f2340f2cfc3f16affa1d37c Mon Sep 17 00:00:00 2001 From: Jacques Dafflon Date: Tue, 26 Mar 2019 01:34:30 +0100 Subject: [PATCH] Automatically merged updates to draft EIP(s) 777 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 --- EIPS/eip-777.md | 215 ++++++++++++++++++++++++------------------------ 1 file changed, 108 insertions(+), 107 deletions(-) diff --git a/EIPS/eip-777.md b/EIPS/eip-777.md index 348569cf..33469c6f 100644 --- a/EIPS/eip-777.md +++ b/EIPS/eip-777.md @@ -43,12 +43,12 @@ The main advantages of this standard are: 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. +5. The 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 `data` and `operatorData` bytes fields - to be used freely to pass data from the token holder and the operator, respectively. + to be used freely to pass data from the 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. @@ -62,11 +62,11 @@ interface ERC777Token { function name() external view returns (string memory); function symbol() external view returns (string memory); function totalSupply() external view returns (uint256); - function balanceOf(address tokenHolder) external view returns (uint256); + function balanceOf(address holder) external view returns (uint256); function granularity() external view returns (uint256); function defaultOperators() external view returns (address[] memory); - function isOperatorFor(address operator, address tokenHolder) external view returns (bool); + function isOperatorFor(address operator, address holder) external view returns (bool); function authorizeOperator(address operator) external; function revokeOperator(address operator) external; @@ -92,8 +92,8 @@ interface ERC777Token { ); event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); - event AuthorizedOperator(address indexed operator, address indexed tokenHolder); - event RevokedOperator(address indexed operator, address indexed tokenHolder); + event AuthorizedOperator(address indexed operator, address indexed holder); + event RevokedOperator(address indexed operator, address indexed holder); } ``` The token contract MUST implement the above interface. @@ -170,17 +170,17 @@ as defined in all the `Minted` events minus the sum of all the burned tokens as **`balanceOf` function** ``` solidity -function balanceOf(address tokenHolder) external view returns (uint256) +function balanceOf(address holder) external view returns (uint256) ``` -Get the balance of the account with address `tokenHolder`. +Get the balance of the account with address `holder`. The balance MUST be zero (`0`) or higher. > **parameters** -> `tokenHolder`: Address for which the balance is returned. +> `holder`: Address for which the balance is returned. > -> **returns:** Amount of tokens held by `tokenHolder` in the token contract. +> **returns:** Amount of tokens held by `holder` in the token contract. **`granularity` function** @@ -226,20 +226,20 @@ Hence for compatibility reasons, `decimals` MUST be implemented for [ERC20] comp #### **Operators** -An `operator` is an address which is allowed to send and burn tokens on behalf of some *token holder*. +An `operator` is an address which is allowed to send and burn tokens on behalf of some *holder*. -When an address becomes an *operator* for a *token holder*, an `AuthorizedOperator` event MUST be emitted. -The `AuthorizedOperator`'s `operator` (topic 1) and `tokenHolder` (topic 2) -MUST be the addresses of the *operator* and the *token holder* respectively. +When an address becomes an *operator* for a *holder*, an `AuthorizedOperator` event MUST be emitted. +The `AuthorizedOperator`'s `operator` (topic 1) and `holder` (topic 2) +MUST be the addresses of the *operator* and the *holder* respectively. -When a *token holder* revokes an *operator*, a `RevokedOperator` event MUST be emitted. -The `RevokedOperator`'s `operator` (topic 1) and `tokenHolder` (topic 2) -MUST be the addresses of the *operator* and the *token holder* respectively. +When a *holder* revokes an *operator*, a `RevokedOperator` event MUST be emitted. +The `RevokedOperator`'s `operator` (topic 1) and `holder` (topic 2) +MUST be the addresses of the *operator* and the *holder* respectively. -*NOTE*: A *token holder* MAY have multiple *operators* at the same time. +*NOTE*: A *holder* MAY have multiple *operators* at the same time. The token MAY define *default operators*. -A *default operator* is an implicitly authorized *operator* for all *token holders*. +A *default operator* is an implicitly authorized *operator* for all *holders*. `AuthorizedOperator` events MUST NOT be emitted when defining the *default operators*. The rules below apply to *default operators*: @@ -249,63 +249,63 @@ The rules below apply to *default operators*: - `AuthorizedOperator` events MUST NOT be emitted when defining *default operators*. -- A *token holder* MUST be allowed revoke a *default operator* - (unless the *token holder* is the *default operator* in question). +- A *holder* MUST be allowed revoke a *default operator* + (unless the *holder* is the *default operator* in question). -- A *token holder* MUST be allowed to re-authorize a previously revoked *default operator*. +- A *holder* MUST be allowed to re-authorize a previously revoked *default operator*. -- When a *default operator* is explicitly authorized or revoked for a specific *token holder*, +- When a *default operator* is explicitly authorized or revoked for a specific *holder*, an `AuthorizedOperator` or `RevokedOperator` event (respectively) MUST be emitted. The following rules apply to any *operator*: - An address MUST always be an *operator* for itself. Hence an address MUST NOT ever be revoked as its own *operator*. -- If an address is an *operator* for a *token holder*, `isOperatorFor` MUST return `true`. +- If an address is an *operator* for a *holder*, `isOperatorFor` MUST return `true`. -- If an address is not an *operator* for a *token holder*, `isOperatorFor` MUST return `false`. +- If an address is not an *operator* for a *holder*, `isOperatorFor` MUST return `false`. - The token contract MUST emit an `AuthorizedOperator` event with the correct values - when a *token holder* authorizes an address as its *operator* as defined in the + when a *holder* authorizes an address as its *operator* as defined in the [`AuthorizedOperator` Event][authorizedoperator]. - The token contract MUST emit a `RevokedOperator` event with the correct values - when a *token holder* revokes an address as its *operator* as defined in the + when a *holder* revokes an address as its *operator* as defined in the [`RevokedOperator` Event][revokedoperator]. -*NOTE*: A *token holder* MAY authorize an already authorized *operator*. +*NOTE*: A *holder* MAY authorize an already authorized *operator*. An `AuthorizedOperator` MUST be emitted each time. -*NOTE*: A *token holder* MAY revoke an already revoked *operator*. +*NOTE*: A *holder* MAY revoke an already revoked *operator*. A `RevokedOperator` MUST be emitted each time. **`AuthorizedOperator` event** ``` solidity -event AuthorizedOperator(address indexed operator, address indexed tokenHolder) +event AuthorizedOperator(address indexed operator, address indexed holder) ``` -Indicates the authorization of `operator` as an *operator* for `tokenHolder`. +Indicates the authorization of `operator` as an *operator* for `holder`. *NOTE*: This event MUST NOT be emitted outside of an *operator* authorization process. > **parameters** -> `operator`: Address which became an *operator* of `tokenHolder`. -> `tokenHolder`: Address of a token holder which authorized the `operator` address as an *operator*. +> `operator`: Address which became an *operator* of `holder`. +> `holder`: Address of a holder which authorized the `operator` address as an *operator*. **`RevokedOperator` event** ``` solidity -event RevokedOperator(address indexed operator, address indexed tokenHolder) +event RevokedOperator(address indexed operator, address indexed holder) ``` -Indicates the revocation of `operator` as an *operator* for `tokenHolder`. +Indicates the revocation of `operator` as an *operator* for `holder`. *NOTE*: This event MUST NOT be emitted outside of an *operator* revocation process. > **parameters** -> `operator`: Address which was revoked as an *operator* of `tokenHolder`. -> `tokenHolder`: Address of a token holder which revoked the `operator` address as an *operator*. +> `operator`: Address which was revoked as an *operator* of `holder`. +> `holder`: Address of a holder which revoked the `operator` address as an *operator*. The `defaultOperators`, `authorizeOperator`, `revokeOperator` and `isOperatorFor` functions described below MUST be implemented to manage *operators*. @@ -331,9 +331,9 @@ function authorizeOperator(address operator) external Set a third party `operator` address as an *operator* of `msg.sender` to send and burn tokens on its behalf. -*NOTE*: The *token holder* (`msg.sender`) is always an *operator* for itself. +*NOTE*: The *holder* (`msg.sender`) is always an *operator* for itself. This right SHALL NOT be revoked. -Hence this function MUST `revert` if it is called to authorize the token holder (`msg.sender`) +Hence this function MUST `revert` if it is called to authorize the holder (`msg.sender`) as an *operator* for itself (i.e. if `operator` is equal to `msg.sender`). > **parameters** @@ -345,11 +345,12 @@ as an *operator* for itself (i.e. if `operator` is equal to `msg.sender`). function revokeOperator(address operator) external ``` -Remove the right of the `operator` address to be an *operator* for `msg.sender` and to send and burn tokens on its behalf. +Remove the right of the `operator` address to be an *operator* for `msg.sender` +and to send and burn tokens on its behalf. -*NOTE*: The *token holder* (`msg.sender`) is always an *operator* for itself. +*NOTE*: The *holder* (`msg.sender`) is always an *operator* for itself. This right SHALL NOT be revoked. -Hence this function MUST `revert` if it is called to revoke the token holder (`msg.sender`) +Hence this function MUST `revert` if it is called to revoke the holder (`msg.sender`) as an *operator* for itself (i.e., if `operator` is equal to `msg.sender`). > **parameters** @@ -358,41 +359,41 @@ as an *operator* for itself (i.e., if `operator` is equal to `msg.sender`). **`isOperatorFor` function** ``` solidity -function isOperatorFor(address operator, address tokenHolder) external view returns (bool) +function isOperatorFor(address operator, address holder) external view returns (bool) ``` -Indicate whether the `operator` address is an *operator* of the `tokenHolder` address. +Indicate whether the `operator` address is an *operator* of the `holder` address. > **parameters** -> `operator`: Address which may be an *operator* of `tokenHolder`. -> `tokenHolder`: Address of a token holder which may have the `operator` address as an *operator*. +> `operator`: Address which may be an *operator* of `holder`. +> `holder`: Address of a holder which may have the `operator` address as an *operator*. > -> **returns:** `true` if `operator` is an *operator* of `tokenHolder` and `false` otherwise. +> **returns:** `true` if `operator` is an *operator* of `holder` and `false` otherwise. -*NOTE*: To know which addresses are *operators* for a given *token holder*, -one MUST call `isOperatorFor` with the *token holder* for each *default operator* -and parse the `AuthorizedOperator`, and `RevokedOperator` events for the *token holder* in question. +*NOTE*: To know which addresses are *operators* for a given *holder*, +one MUST call `isOperatorFor` with the *holder* for each *default operator* +and parse the `AuthorizedOperator`, and `RevokedOperator` events for the *holder* in question. #### **Sending Tokens** -When an *operator* sends an `amount` of tokens from a *token holder* to a *recipient* +When an *operator* sends an `amount` of tokens from a *holder* to a *recipient* with the associated `data` and `operatorData`, the token contract MUST apply the following rules: - Any authorized *operator* MAY send tokens to any *recipient* (except to `0x0`). -- The balance of the *token holder* MUST be decreased by the `amount`. +- The balance of the *holder* MUST be decreased by the `amount`. - 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 +- The balance of the *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 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 [ERC1820]. +- The token contract MUST call the `tokensToSend` hook of the *holder* + if the *holder* registers an `ERC777TokensSender` implementation via [ERC1820]. - The token contract MUST call the `tokensReceived` hook of the *recipient* if the *recipient* registers an `ERC777TokensRecipient` implementation via [ERC1820]. @@ -402,23 +403,23 @@ with the associated `data` and `operatorData`, the token contract MUST apply the The token contract MUST `revert` when sending in any of the following cases: -- The *operator* address is not an authorized operator for the *token holder*. +- The *operator* address is not an authorized operator for the *holder*. -- The resulting *token holder* balance or *recipient* balance after the send +- The resulting *holder* balance or *recipient* balance after the send is not a multiple of the *granularity* defined by the token contract. - The *recipient* is a contract, and it does not implement the `ERC777TokensRecipient` interface via [ERC1820]. -- The address of the *token holder* or the *recipient* is `0x0`. +- The address of the *holder* or the *recipient* is `0x0`. - Any of the resulting balances becomes negative, i.e. becomes less than zero (`0`). -The token contract MAY send tokens from many *token holders*, to many *recipients*, or both. In this case: +The token contract MAY send tokens from many *holders*, to many *recipients*, or both. In this case: -- The previous send rules MUST apply to all the *token holders* and all the *recipients*. +- The previous send rules MUST apply to all the *holders* and all the *recipients*. - The sum of all the balances incremented MUST be equal to the total sent `amount`. - The sum of all the balances decremented MUST be equal to the total sent `amount`. -- A `Sent` event MUST be emitted for every *token holder* and *recipient* pair with the corresponding amount for each pair. +- A `Sent` event MUST be emitted for every *holder* and *recipient* pair with the corresponding amount for each pair. - The sum of all the amounts from the `Sent` event MUST be equal to the total sent `amount`. *NOTE*: Mechanisms such as applying a fee on a send is considered as a send to multiple *recipients*: @@ -439,7 +440,7 @@ 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 information provided by the token holder—similar +*NOTE*: The `data` field contains information provided by the *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. @@ -463,10 +464,10 @@ Indicate a send of `amount` of tokens from the `from` address to the `to` addres > **parameters** > `operator`: Address which triggered the send. -> `from`: Token holder. +> `from`: Holder. > `to`: Token recipient. > `amount`: Number of tokens to send. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. The `send` and `operatorSend` functions described below MUST be implemented to send tokens. @@ -480,12 +481,12 @@ function send(address to, uint256 amount, bytes calldata data) external Send the `amount` of tokens from the address `msg.sender` to the address `to`. -The *operator* and the *token holder* MUST both be the `msg.sender`. +The *operator* and the *holder* MUST both be the `msg.sender`. > **parameters** > `to`: Token recipient. > `amount`: Number of tokens to send. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. **`operatorSend` function** @@ -497,7 +498,7 @@ Send the `amount` of tokens on behalf of the address `from` to the address `to`. The *operator* MUST be `msg.sender`. The value of `from` MAY be `0x0`, -then the `from` (*token holder*) used for the send MUST be `msg.sender` (the `operator`). +then the `from` (*holder*) used for the send MUST be `msg.sender` (the `operator`). *Reminder*: If the *operator* address is not an authorized operator of the `from` address, then the send process MUST `revert`. @@ -509,10 +510,10 @@ that the *operator* MAY specify an explicit value for `operatorData` (which cannot be done with the `send` function). > **parameters** -> `from`: Token holder (or `0x0` to set `from` to `msg.sender`). +> `from`: Holder (or `0x0` to set `from` to `msg.sender`). > `to`: Token recipient. > `amount`: Number of tokens to send. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. #### **Minting Tokens** @@ -585,7 +586,7 @@ 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 provided by the *token holder*. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. #### **Burning Tokens** @@ -593,54 +594,54 @@ Indicate the minting of `amount` of tokens to the `to` address by the `operator` Burning tokens is the act of destroying existing tokens. [ERC777] explicitly defines two functions to burn tokens (`burn` and `operatorBurn`). These functions facilitate the integration of the burning process in wallets and dapps. -However, the token contract MAY prevent some or all *token holders* from burning tokens for any reason. +However, the token contract MAY prevent some or all *holders* from burning tokens for any reason. The token contract MAY also define other functions to burn tokens. -The rules below MUST be respected when burning the tokens of a *token holder*: +The rules below MUST be respected when burning the tokens of a *holder*: -- Tokens MAY be burned from any *token holder* address. +- Tokens MAY be burned from any *holder* address. - The total supply MUST be decreased by the amount of tokens burned. - The balance of `0x0` MUST NOT be increased. -- The balance of the *token holder* MUST be decreased by amount of tokens burned. +- The balance of the *holder* MUST be decreased by amount of tokens burned. - 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 [ERC1820]. +- The token contract MUST call the `tokensToSend` hook of the *holder* + if the *holder* registers an `ERC777TokensSender` implementation via [ERC1820]. - 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 token contract MUST `revert` when burning in any of the following cases: -- The *operator* address is not an authorized operator for the *token holder*. +- The *operator* address is not an authorized operator for the *holder*. -- The resulting *token holder* balance after the burn is not a multiple of the *granularity* +- The resulting *holder* balance after the burn is not a multiple of the *granularity* defined by the token contract. -- The balance of *token holder* is inferior to the amount of tokens to burn - (i.e., resulting in a negative balance for the *token holder*). +- The balance of *holder* is inferior to the amount of tokens to burn + (i.e., resulting in a negative balance for the *holder*). -- The address of the *token holder* is `0x0`. +- The address of the *holder* is `0x0`. *[ERC20] compatibility requirement*: While a `Sent` event MUST NOT be emitted when burning; if the token contract is [ERC20] enabled, a `Transfer` event with the `to` parameter set to `0x0` SHOULD be emitted. The [ERC20] standard does not define the concept of burning tokens, but this is a commonly accepted practice. -The token contract MAY burn tokens for multiple *token holders* at once. In this case: +The token contract MAY burn tokens for multiple *holders* at once. In this case: -- The previous burn rules MUST apply to each *token holders*. +- The previous burn rules MUST apply to each *holders*. - The sum of all the balances decremented MUST be equal to the total burned amount. -- A `Burned` event MUST be emitted for every *token holder* with the corresponding amount for each *token holder*. +- A `Burned` event MUST be emitted for every *holder* with the corresponding amount for each *holder*. - The sum of all the amounts from the `Burned` event MUST be equal to the total burned `amount`. *NOTE*: Burning an amount of zero (`0`) tokens is valid and MUST be treated as a regular burn. -*NOTE*: The `data` field contains information provided by the token holder—similar +*NOTE*: The `data` field contains information provided by the 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. @@ -659,9 +660,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. +> `from`: Holder whose tokens are burned. > `amount`: Number of tokens burned. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. The `burn` and `operatorBurn` functions described below MUST be implemented to burn tokens. @@ -675,11 +676,11 @@ function burn(uint256 amount, bytes calldata data) external Burn the `amount` of tokens from the address `msg.sender`. -The *operator* and the *token holder* MUST both be the `msg.sender`. +The *operator* and the *holder* MUST both be the `msg.sender`. > **parameters** > `amount`: Number of tokens to burn. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. **`operatorBurn` function** @@ -691,15 +692,15 @@ Burn the `amount` of tokens on behalf of the address `from`. The *operator* MUST be `msg.sender`. The value of `from` MAY be `0x0`, -then the `from` (*token holder*) used for the burn MUST be `msg.sender` (the `operator`). +then the `from` (*holder*) used for the burn MUST be `msg.sender` (the `operator`). *Reminder*: If the *operator* address is not an authorized operator of the `from` address, then the burn process MUST `revert`. > **parameters** -> `from`: Token holder whose tokens will be burned (or `0x0` to set `from` to `msg.sender`). +> `from`: Holder whose tokens will be burned (or `0x0` to set `from` to `msg.sender`). > `amount`: Number of tokens to burn. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. *NOTE*: The *operator* MAY pass any information via `operatorData`. @@ -713,7 +714,7 @@ with the addition that the *operator* MAY specify an explicit value for `operato #### **`ERC777TokensSender` And The `tokensToSend` Hook** -The `tokensToSend` hook notifies of any decrement of balance (send and burn) for a given *token holder*. +The `tokensToSend` hook notifies of any decrement of balance (send and burn) for a given *holder*. Any address (regular or contract) wishing to be notified of token debits from their address MAY register the address of a contract implementing the `ERC777TokensSender` interface described below via [ERC1820]. @@ -748,10 +749,10 @@ by the `operator` address. > **parameters** > `operator`: Address which triggered the balance decrease (through sending or burning). -> `from`: *token holder*. +> `from`: *holder*. > `to`: *token recipient* for a send and `0x` for a burn. -> `amount`: Number of tokens the *token holder* balance is decreased by. -> `data`: Information provided by the *token holder*. +> `amount`: Number of tokens the *holder* balance is decreased by. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. The following rules apply when calling the `tokensToSend` hook: @@ -762,23 +763,23 @@ The following rules apply when calling the `tokensToSend` hook: - `operator` MUST be the address which triggered the decrease of the balance. -- `from` MUST be the address of the *token holder* whose balance is decreased. +- `from` MUST be the address of the *holder* whose balance is decreased. - `to` MUST be the address of the *recipient* whose balance is increased for a send. - `to` MUST be `0x0` for a burn. -- `amount` MUST be the number of tokens the *token holder* balance is decreased by. +- `amount` MUST be the number of tokens the *holder* balance is decreased by. -- `data` MUST contain the extra information provided by the *token holder* (if any) for a send. +- `data` MUST contain the extra information provided by the *holder* (if any) for a send. - `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. +- The *holder* MAY block a decrease of its balance by `revert`ing. (I.e., reject the withdrawal of tokens from its account.) -*NOTE*: Multiple *token holders* MAY use the same implementation of `ERC777TokensSender`. +*NOTE*: Multiple *holders* MAY use the same implementation of `ERC777TokensSender`. *NOTE*: An address can register at most one implementation at any given time for all [ERC777] tokens. Hence the `ERC777TokensSender` MUST expect to be called by different token contracts. @@ -833,10 +834,10 @@ by the `operator` address. > **parameters** > `operator`: Address which triggered the balance increase (through sending or minting). -> `from`: *token holder* for a send and `0x` for a mint. +> `from`: *holder* for a send and `0x` for a mint. > `to`: *token recipient*. > `amount`: Number of tokens the *recipient* balance is increased by. -> `data`: Information provided by the *token holder*. +> `data`: Information provided by the *holder*. > `operatorData`: Information provided by the *operator*. The following rules apply when calling the `tokensReceived` hook: @@ -847,7 +848,7 @@ The following rules apply when calling the `tokensReceived` hook: - `operator` MUST be the address which triggered the increase of the balance. -- `from` MUST be the address of the *token holder* whose balance is decreased for a send. +- `from` MUST be the address of the *holder* whose balance is decreased for a send. - `from` MUST be `0x0` for a mint. @@ -857,9 +858,9 @@ The following rules apply when calling the `tokensReceived` hook: - `operatorData` MUST contain the extra information provided by the address which triggered the increase of the balance (if any). -- The *token holder* MAY block an increase of its balance by `revert`ing. (I.e., reject the reception of tokens.) +- The *holder* MAY block an increase of its balance by `revert`ing. (I.e., reject the reception of tokens.) -*NOTE*: Multiple *token holders* MAY use the same implementation of `ERC777TokensRecipient`. +*NOTE*: Multiple *holders* MAY use the same implementation of `ERC777TokensRecipient`. *NOTE*: An address can register at most one implementation at any given time for all [ERC777] tokens. Hence the `ERC777TokensRecipient` MUST expect to be called by different token contracts. @@ -902,7 +903,7 @@ It avoids the problems and vulnerabilities of [EIP223]. It goes a step further by allowing *operators* (generally contracts) which can manage the tokens in the same way that the [ERC20] with infinite `approve` was allowed. -Finally, it adds hooks to provide further control to *token holders* over their tokens. +Finally, it adds hooks to provide further control to *holders* over their tokens. Note that, the usage of [ERC1820] provides backward compatibility with wallets and existing contracts without having to be redeployed thanks proxy contracts implementing the hooks.