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
This commit is contained in:
Jacques Dafflon 2019-03-26 01:34:30 +01:00 committed by EIP Automerge Bot
parent 9e4283608c
commit 4eb6eab9cb

View File

@ -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.
> <small>**parameters**</small>
> <small>`tokenHolder`: Address for which the balance is returned.</small>
> <small>`holder`: Address for which the balance is returned.</small>
>
> <small>**returns:** Amount of tokens held by `tokenHolder` in the token contract.</small>
> <small>**returns:** Amount of tokens held by `holder` in the token contract.</small>
**`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** <a id="authorizedoperator"></a>
``` 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.
> <small>**parameters**</small>
> <small>`operator`: Address which became an *operator* of `tokenHolder`.</small>
> <small>`tokenHolder`: Address of a token holder which authorized the `operator` address as an *operator*.</small>
> <small>`operator`: Address which became an *operator* of `holder`.</small>
> <small>`holder`: Address of a holder which authorized the `operator` address as an *operator*.</small>
**`RevokedOperator` event** <a id="revokedoperator"></a>
``` 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.
> <small>**parameters**</small>
> <small>`operator`: Address which was revoked as an *operator* of `tokenHolder`.</small>
> <small>`tokenHolder`: Address of a token holder which revoked the `operator` address as an *operator*.</small>
> <small>`operator`: Address which was revoked as an *operator* of `holder`.</small>
> <small>`holder`: Address of a holder which revoked the `operator` address as an *operator*.</small>
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`).
> <small>**parameters**</small>
@ -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`).
> <small>**parameters**</small>
@ -358,41 +359,41 @@ as an *operator* for itself (i.e., if `operator` is equal to `msg.sender`).
**`isOperatorFor` function** <a id="isOperatorFor"></a>
``` 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.
> <small>**parameters**</small>
> <small>`operator`: Address which may be an *operator* of `tokenHolder`.</small>
> <small>`tokenHolder`: Address of a token holder which may have the `operator` address as an *operator*.</small>
> <small>`operator`: Address which may be an *operator* of `holder`.</small>
> <small>`holder`: Address of a holder which may have the `operator` address as an *operator*.</small>
>
> <small>**returns:** `true` if `operator` is an *operator* of `tokenHolder` and `false` otherwise.
> <small>**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`&mdash;such
- The balance of the *holder* MUST be greater or equal to the `amount`&mdash;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&mdash;similar
*NOTE*: The `data` field contains information provided by the *holder*&mdash;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
> <small>**parameters**</small>
> <small>`operator`: Address which triggered the send.</small>
> <small>`from`: Token holder.</small>
> <small>`from`: Holder.</small>
> <small>`to`: Token recipient.</small>
> <small>`amount`: Number of tokens to send.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
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`.
> <small>**parameters**</small>
> <small>`to`: Token recipient.</small>
> <small>`amount`: Number of tokens to send.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
**`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).
> <small>**parameters**</small>
> <small>`from`: Token holder (or `0x0` to set `from` to `msg.sender`).</small>
> <small>`from`: Holder (or `0x0` to set `from` to `msg.sender`).</small>
> <small>`to`: Token recipient.</small>
> <small>`amount`: Number of tokens to send.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
#### **Minting Tokens**
@ -585,7 +586,7 @@ Indicate the minting of `amount` of tokens to the `to` address by the `operator`
> <small>`operator`: Address which triggered the mint.</small>
> <small>`to`: Token recipient.</small>
> <small>`amount`: Number of tokens minted.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
#### **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&mdash;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&mdash;similar
*NOTE*: The `data` field contains information provided by the holder&mdash;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
> <small>**parameters**</small>
> <small>`operator`: Address which triggered the burn.</small>
> <small>`from`: Token holder whose tokens are burned.</small>
> <small>`from`: Holder whose tokens are burned.</small>
> <small>`amount`: Number of tokens burned.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
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`.
> <small>**parameters**</small>
> <small>`amount`: Number of tokens to burn.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
**`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`.
> <small>**parameters**</small>
> <small>`from`: Token holder whose tokens will be burned (or `0x0` to set `from` to `msg.sender`).</small>
> <small>`from`: Holder whose tokens will be burned (or `0x0` to set `from` to `msg.sender`).</small>
> <small>`amount`: Number of tokens to burn.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
*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.
> <small>**parameters**</small>
> <small>`operator`: Address which triggered the balance decrease (through sending or burning).</small>
> <small>`from`: *token holder*.</small>
> <small>`from`: *holder*.</small>
> <small>`to`: *token recipient* for a send and `0x` for a burn.</small>
> <small>`amount`: Number of tokens the *token holder* balance is decreased by.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`amount`: Number of tokens the *holder* balance is decreased by.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
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.
> <small>**parameters**</small>
> <small>`operator`: Address which triggered the balance increase (through sending or minting).</small>
> <small>`from`: *token holder* for a send and `0x` for a mint.</small>
> <small>`from`: *holder* for a send and `0x` for a mint.</small>
> <small>`to`: *token recipient*.</small>
> <small>`amount`: Number of tokens the *recipient* balance is increased by.</small>
> <small>`data`: Information provided by the *token holder*.</small>
> <small>`data`: Information provided by the *holder*.</small>
> <small>`operatorData`: Information provided by the *operator*.</small>
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.