mirror of
https://github.com/status-im/EIPs.git
synced 2025-02-05 11:34:35 +00:00
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:
parent
9e4283608c
commit
4eb6eab9cb
215
EIPS/eip-777.md
215
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.
|
||||
|
||||
> <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`—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
|
||||
|
||||
> <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—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
|
||||
|
||||
> <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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user