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.

Events

constructor constructor(string name, string symbol, address[] defaultOperators) public

defaultOperators may be an empty array.

name name() → string public

See {IERC777-name}.

symbol symbol() → string public

See {IERC777-symbol}.

decimals decimals() → uint8 public

See {ERC20-decimals}.

Always returns 18, as per the [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).

granularity granularity() → uint256 public

See {IERC777-granularity}.

This implementation always returns 1.

totalSupply totalSupply() → uint256 public

See {IERC777-totalSupply}.

balanceOf balanceOf(address tokenHolder) → uint256 public

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

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

See {IERC777-send}.

Also emits a {IERC20-Transfer} event for ERC20 compatibility.

transfer 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 burn(uint256 amount, bytes data) public

See {IERC777-burn}.

Also emits a {IERC20-Transfer} event for ERC20 compatibility.

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

See {IERC777-isOperatorFor}.

authorizeOperator authorizeOperator(address operator) public

See {IERC777-authorizeOperator}.

revokeOperator revokeOperator(address operator) public

See {IERC777-revokeOperator}.

defaultOperators defaultOperators() → address[] public

See {IERC777-defaultOperators}.

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

See {IERC777-operatorSend}.

Emits {Sent} and {IERC20-Transfer} events.

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

See {IERC777-operatorBurn}.

Emits {Burned} and {IERC20-Transfer} events.

allowance 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 approve(address spender, uint256 value) → bool public

See {IERC20-approve}.

Note that accounts cannot have allowance issued by their operators.

transferFrom 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 _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 _send(address from, address to, uint256 amount, bytes userData, bytes operatorData, bool requireReceptionAck) internal

Send tokens

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

Burn tokens

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

See {ERC20-_approve}.

Note that accounts cannot have allowance issued by their operators.

_callTokensToSend _callTokensToSend(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData) internal

Call from.tokensToSend() if the interface is registered

_callTokensReceived _callTokensReceived(address operator, address from, address to, uint256 amount, bytes userData, bytes operatorData, bool requireReceptionAck) internal

Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but tokensReceived() was not registered for the recipient

_beforeTokenTransfer _beforeTokenTransfer(address operator, address from, address to, uint256 tokenId) internal

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

Calling conditions:

  • when from and to are both non-zero, from's tokenId will be transferred to to.

  • when from is zero, tokenId will be minted for to.

  • when to is zero, from's tokenId will be burned.

  • from and to are never both zero.

To learn more about hooks, head to Using Hooks.