ERC 777

Outdated Version

You're viewing an older version (v3.x) The latest documentation is available for the current version. Click here to visit latest version.

This set of interfaces and contracts are all related to the ERC777 token standard.

For an overview of ERC777 tokens and a walk through on how to create a token contract read our ERC777 guide.

The token behavior itself is implemented in the core contracts: IERC777, ERC777.

Additionally there are interfaces used to develop contracts that react to token movements: IERC777Sender, IERC777Recipient.

Core

IERC777

Interface of the ERC777Token standard as defined in the EIP.

This contract uses the ERC1820 registry standard to let token holders and recipients react to token movements by using setting implementers for the associated interfaces in said registry. See IERC1820Registry and ERC1820Implementer.

Functions

Events

name() → string *external*

Returns the name of the token.

symbol() → string *external*

Returns the symbol of the token, usually a shorter version of the name.

granularity() → uint256 *external*

Returns the smallest part of the token that is not divisible. This means all token operations (creation, movement and destruction) must have amounts that are a multiple of this number.

For most token contracts, this value will equal 1.

totalSupply() → uint256 *external*

Returns the amount of tokens in existence.

balanceOf(address owner) → uint256 *external*

Returns the amount of tokens owned by an account (owner).

send(address recipient, uint256 amount, bytes data) *external*

Moves amount tokens from the caller’s account to recipient.

If send or receive hooks are registered for the caller and recipient, the corresponding functions will be called with data and empty operatorData. See IERC777Sender and IERC777Recipient.

Emits a Sent event.

Requirements

  • the caller must have at least amount tokens.
  • recipient cannot be the zero address.
  • if recipient is a contract, it must implement the IERC777Recipient interface.

burn(uint256 amount, bytes data) *external*

Destroys amount tokens from the caller’s account, reducing the total supply.

If a send hook is registered for the caller, the corresponding function will be called with data and empty operatorData. See IERC777Sender.

Emits a Burned event.

Requirements

  • the caller must have at least amount tokens.

isOperatorFor(address operator, address tokenHolder) → bool *external*

Returns true if an account is an operator of tokenHolder. Operators can send and burn tokens on behalf of their owners. All accounts are their own operator.

See operatorSend and operatorBurn.

`authorizeOperator(address operator) external

Make an account an operator of the caller.

See isOperatorFor.

Emits an AuthorizedOperator event.

Requirements

* operator` cannot be calling address.

`revokeOperator(address operator) external

Revoke an account’s operator status for the caller.

See isOperatorFor and defaultOperators.

Emits a RevokedOperator event.

Requirements

* operator` cannot be calling address.

defaultOperators() → address[] *external*

Returns the list of default operators. These accounts are operators for all token holders, even if authorizeOperator was never called on them.

This list is immutable, but individual holders may revoke these via revokeOperator, in which case isOperatorFor will return false.

operatorSend(address sender, address recipient, uint256 amount, bytes data, bytes operatorData) *external*

Moves amount tokens from sender to recipient. The caller must be an operator of sender.

If send or receive hooks are registered for sender and recipient, the corresponding functions will be called with data and operatorData. See IERC777Sender and IERC777Recipient.

Emits a Sent event.

Requirements

  • sender cannot be the zero address.
  • sender must have at least amount tokens.
  • the caller must be an operator for sender.
  • recipient cannot be the zero address.
  • if recipient is a contract, it must implement the IERC777Recipient interface.

operatorBurn(address account, uint256 amount, bytes data, bytes operatorData) *external*

Destroys amount tokens from account, reducing the total supply. The caller must be an operator of account.

If a send hook is registered for account, the corresponding function will be called with data and operatorData. See IERC777Sender.

Emits a Burned event.

Requirements

  • account cannot be the zero address.
  • account must have at least amount tokens.
  • the caller must be an operator for account.

Sent(address operator, address from, address to, uint256 amount, bytes data, bytes operatorData) *event*

Minted(address operator, address to, uint256 amount, bytes data, bytes operatorData) *event*

Burned(address operator, address from, uint256 amount, bytes data, bytes operatorData) *event*

AuthorizedOperator(address operator, address tokenHolder) *event*

RevokedOperator(address operator, address tokenHolder) *event*

ERC777

Implementation of the IERC777 interface.

This implementation is agnostic to the way tokens are created. This means that a supply mechanism has to be added in a derived contract using _mint.

Support for ERC20 is included in this contract, as specified by the EIP: both the ERC777 and ERC20 interfaces can be safely used when interacting with it. Both IERC777-Sent and IERC20-Transfer events are emitted on token movements.

Additionally, the IERC777-granularity value is hard-coded to 1, meaning that there are no special restrictions in the amount of tokens that created, moved, or destroyed. This makes integration with ERC20 applications seamless.

Functions

Events

IERC20

IERC777

constructor(string name_, string symbol_, address[] defaultOperators_) *public*

defaultOperators may be an empty array.

name() → string *public*

See IERC777-name.

symbol() → string *public*

See IERC777-symbol.

decimals() → uint8 *public*

See ERC20-decimals.

Always returns 18, as per the ERC777 EIP.

granularity() → uint256 *public*

See IERC777-granularity.

This implementation always returns 1.

totalSupply() → uint256 *public*

See IERC777-totalSupply.

balanceOf(address tokenHolder) → uint256 *public*

Returns the amount of tokens owned by an account (tokenHolder).

send(address recipient, uint256 amount, bytes data) *public*

See IERC777-send.

Also emits a IERC20-Transfer event for ERC20 compatibility.

transfer(address recipient, uint256 amount) → bool *public*

See IERC20-transfer.

Unlike send, recipient is not required to implement the IERC777Recipient interface if it is a contract.

Also emits a Sent event.

burn(uint256 amount, bytes data) *public*

See IERC777-burn.

Also emits a IERC20-Transfer event for ERC20 compatibility.

isOperatorFor(address operator, address tokenHolder) → bool *public*

See IERC777-isOperatorFor.

authorizeOperator(address operator) *public*

See IERC777-authorizeOperator.

revokeOperator(address operator) *public*

See IERC777-revokeOperator.

defaultOperators() → address[] *public*

See IERC777-defaultOperators.

operatorSend(address sender, address recipient, uint256 amount, bytes data, bytes operatorData) *public*

See IERC777-operatorSend.

Emits Sent and IERC20-Transfer events.

operatorBurn(address account, uint256 amount, bytes data, bytes operatorData) *public*

See IERC777-operatorBurn.

Emits Burned and IERC20-Transfer events.

allowance(address holder, address spender) → uint256 *public*

See IERC20-allowance.

Note that operator and allowance concepts are orthogonal: operators may not have allowance, and accounts with allowance may not be operators themselves.

approve(address spender, uint256 value) → bool *public*

See IERC20-approve.

Note that accounts cannot have allowance issued by their operators.

transferFrom(address holder, address recipient, uint256 amount) → bool *public*

See IERC20-transferFrom.

Note that operator and allowance concepts are orthogonal: operators cannot call transferFrom (unless they have allowance), and accounts with allowance cannot call operatorSend (unless they are operators).

Emits Sent, IERC20-Transfer and IERC20-Approval events.

_mint(address account, uint256 amount, bytes userData, bytes operatorData) *internal*

Creates amount tokens and assigns them to account, increasing the total supply.

If a send hook is registered for account, the corresponding function will be called with operator, data and operatorData.

See IERC777Sender and IERC777Recipient.

Emits Minted and IERC20-Transfer events.

Requirements

  • account cannot be the zero address.
  • if account is a contract, it must implement the IERC777Recipient interface.

_send(address from, address to, uint256 amount, bytes userData, bytes operatorData, bool requireReceptionAck) *internal*

Send tokens

_burn(address from, uint256 amount, bytes data, bytes operatorData) *internal*

Burn tokens

_approve(address holder, address spender, uint256 value) *internal*

See ERC20-_approve.

Note that accounts cannot have allowance issued by their operators.

`_beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal

Hook that is called before any token transfer. This includes calls to send, transfer, operatorSend, minting and burning.

Calling conditions:

*whenfromandtoare both non-zero,amount of ``from’s tokens will be to transferred to to.

  • when from is zero, amount tokens will be minted for to.
  • when to is zero, amount of ``from`’s tokens will be burned.
  • from and to are never both zero.

To learn more about hooks, head to Using Hooks.

Hooks

IERC777Sender

Interface of the ERC777TokensSender standard as defined in the EIP.

IERC777 Token holders can be notified of operations performed on their tokens by having a contract implement this interface (contract holders can be their own implementer) and registering it on the ERC1820 global registry.

See IERC1820Registry and ERC1820Implementer.

Functions

tokensToSend(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData) *external*

Called by an IERC777 token contract whenever a registered holder’s (from) tokens are about to be moved or destroyed. The type of operation is conveyed by to being the zero address or not.

This call occurs before the token contract’s state is updated, so IERC777-balanceOf, etc., can be used to query the pre-operation state.

This function may revert to prevent the operation from being executed.

IERC777Recipient

Interface of the ERC777TokensRecipient standard as defined in the EIP.

Accounts can be notified of IERC777 tokens being sent to them by having a contract implement this interface (contract holders can be their own implementer) and registering it on the ERC1820 global registry.

See IERC1820Registry and ERC1820Implementer.

Functions

tokensReceived(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData) *external*

Called by an IERC777 token contract whenever tokens are being moved or created into a registered account (to). The type of operation is conveyed by from being the zero address or not.

This call occurs after the token contract’s state is updated, so IERC777-balanceOf, etc., can be used to query the post-operation state.

This function may revert to prevent the operation from being executed.

On this page

CoreIERC777name() → string *external*symbol() → string *external*granularity() → uint256 *external*totalSupply() → uint256 *external*balanceOf(address owner) → uint256 *external*send(address recipient, uint256 amount, bytes data) *external*burn(uint256 amount, bytes data) *external*isOperatorFor(address operator, address tokenHolder) → bool *external*`authorizeOperator(address operator) external`revokeOperator(address operator) externaldefaultOperators() → address[] *external*operatorSend(address sender, address recipient, uint256 amount, bytes data, bytes operatorData) *external*operatorBurn(address account, uint256 amount, bytes data, bytes operatorData) *external*Sent(address operator, address from, address to, uint256 amount, bytes data, bytes operatorData) *event*Minted(address operator, address to, uint256 amount, bytes data, bytes operatorData) *event*Burned(address operator, address from, uint256 amount, bytes data, bytes operatorData) *event*AuthorizedOperator(address operator, address tokenHolder) *event*RevokedOperator(address operator, address tokenHolder) *event*ERC777constructor(string name_, string symbol_, address[] defaultOperators_) *public*name() → string *public*symbol() → string *public*decimals() → uint8 *public*granularity() → uint256 *public*totalSupply() → uint256 *public*balanceOf(address tokenHolder) → uint256 *public*send(address recipient, uint256 amount, bytes data) *public*transfer(address recipient, uint256 amount) → bool *public*burn(uint256 amount, bytes data) *public*isOperatorFor(address operator, address tokenHolder) → bool *public*authorizeOperator(address operator) *public*revokeOperator(address operator) *public*defaultOperators() → address[] *public*operatorSend(address sender, address recipient, uint256 amount, bytes data, bytes operatorData) *public*operatorBurn(address account, uint256 amount, bytes data, bytes operatorData) *public*allowance(address holder, address spender) → uint256 *public*approve(address spender, uint256 value) → bool *public*transferFrom(address holder, address recipient, uint256 amount) → bool *public*_mint(address account, uint256 amount, bytes userData, bytes operatorData) *internal*_send(address from, address to, uint256 amount, bytes userData, bytes operatorData, bool requireReceptionAck) *internal*_burn(address from, uint256 amount, bytes data, bytes operatorData) *internal*_approve(address holder, address spender, uint256 value) *internal*`_beforeTokenTransfer(address operator, address from, address to, uint256 amount) internalHooksIERC777SendertokensToSend(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData) *external*IERC777RecipienttokensReceived(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData) *external*