Remove code in preparation for v5.0 (#4258)
Co-authored-by: Ernesto García <ernestognw@gmail.com> Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
@ -23,14 +23,6 @@ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces {
|
||||
// solhint-disable-next-line var-name-mixedcase
|
||||
bytes32 private constant _PERMIT_TYPEHASH =
|
||||
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
|
||||
/**
|
||||
* @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
|
||||
* However, to ensure consistency with the upgradeable transpiler, we will continue
|
||||
* to reserve a slot.
|
||||
* @custom:oz-renamed-from _PERMIT_TYPEHASH
|
||||
*/
|
||||
// solhint-disable-next-line var-name-mixedcase
|
||||
bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;
|
||||
|
||||
/**
|
||||
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
// EIP-2612 is Final as of 2022-11-01. This file is deprecated.
|
||||
|
||||
import "./ERC20Permit.sol";
|
||||
@ -1,7 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
// EIP-2612 is Final as of 2022-11-01. This file is deprecated.
|
||||
|
||||
import "./IERC20Permit.sol";
|
||||
@ -35,24 +35,6 @@ library SafeERC20 {
|
||||
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deprecated. This function has issues similar to the ones found in
|
||||
* {IERC20-approve}, and its usage is discouraged.
|
||||
*
|
||||
* Whenever possible, use {safeIncreaseAllowance} and
|
||||
* {safeDecreaseAllowance} instead.
|
||||
*/
|
||||
function safeApprove(IERC20 token, address spender, uint256 value) internal {
|
||||
// safeApprove should only be called when setting an initial allowance,
|
||||
// or when resetting it to zero. To increase and decrease it, use
|
||||
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
|
||||
require(
|
||||
(value == 0) || (token.allowance(address(this), spender) == 0),
|
||||
"SafeERC20: approve from non-zero to non-zero allowance"
|
||||
);
|
||||
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
|
||||
* non-reverting calls are assumed to be successful.
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/draft-ERC721Votes.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
// ERC721Votes was marked as draft due to the EIP-712 dependency.
|
||||
// EIP-712 is Final as of 2022-08-11. This file is deprecated.
|
||||
|
||||
import "./ERC721Votes.sol";
|
||||
@ -1,517 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC777/ERC777.sol)
|
||||
|
||||
pragma solidity ^0.8.1;
|
||||
|
||||
import "./IERC777.sol";
|
||||
import "./IERC777Recipient.sol";
|
||||
import "./IERC777Sender.sol";
|
||||
import "../ERC20/IERC20.sol";
|
||||
import "../../utils/Address.sol";
|
||||
import "../../utils/Context.sol";
|
||||
import "../../utils/introspection/IERC1820Registry.sol";
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*
|
||||
* CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.
|
||||
*/
|
||||
contract ERC777 is Context, IERC777, IERC20 {
|
||||
using Address for address;
|
||||
|
||||
IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
|
||||
|
||||
mapping(address => uint256) private _balances;
|
||||
|
||||
uint256 private _totalSupply;
|
||||
|
||||
string private _name;
|
||||
string private _symbol;
|
||||
|
||||
bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
|
||||
bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
|
||||
|
||||
// This isn't ever read from - it's only used to respond to the defaultOperators query.
|
||||
address[] private _defaultOperatorsArray;
|
||||
|
||||
// Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
|
||||
mapping(address => bool) private _defaultOperators;
|
||||
|
||||
// For each account, a mapping of its operators and revoked default operators.
|
||||
mapping(address => mapping(address => bool)) private _operators;
|
||||
mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
|
||||
|
||||
// ERC20-allowances
|
||||
mapping(address => mapping(address => uint256)) private _allowances;
|
||||
|
||||
/**
|
||||
* @dev `defaultOperators` may be an empty array.
|
||||
*/
|
||||
constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {
|
||||
_name = name_;
|
||||
_symbol = symbol_;
|
||||
|
||||
_defaultOperatorsArray = defaultOperators_;
|
||||
for (uint256 i = 0; i < defaultOperators_.length; i++) {
|
||||
_defaultOperators[defaultOperators_[i]] = true;
|
||||
}
|
||||
|
||||
// register interfaces
|
||||
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
|
||||
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-name}.
|
||||
*/
|
||||
function name() public view virtual override returns (string memory) {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-symbol}.
|
||||
*/
|
||||
function symbol() public view virtual override returns (string memory) {
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {ERC20-decimals}.
|
||||
*
|
||||
* Always returns 18, as per the
|
||||
* [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
|
||||
*/
|
||||
function decimals() public pure virtual returns (uint8) {
|
||||
return 18;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-granularity}.
|
||||
*
|
||||
* This implementation always returns `1`.
|
||||
*/
|
||||
function granularity() public view virtual override returns (uint256) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-totalSupply}.
|
||||
*/
|
||||
function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {
|
||||
return _totalSupply;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the amount of tokens owned by an account (`tokenHolder`).
|
||||
*/
|
||||
function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {
|
||||
return _balances[tokenHolder];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-send}.
|
||||
*
|
||||
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
|
||||
*/
|
||||
function send(address recipient, uint256 amount, bytes memory data) public virtual override {
|
||||
_send(_msgSender(), recipient, amount, data, "", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-transfer}.
|
||||
*
|
||||
* Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
|
||||
* interface if it is a contract.
|
||||
*
|
||||
* Also emits a {Sent} event.
|
||||
*/
|
||||
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
|
||||
_send(_msgSender(), recipient, amount, "", "", false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-burn}.
|
||||
*
|
||||
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
|
||||
*/
|
||||
function burn(uint256 amount, bytes memory data) public virtual override {
|
||||
_burn(_msgSender(), amount, data, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-isOperatorFor}.
|
||||
*/
|
||||
function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {
|
||||
return
|
||||
operator == tokenHolder ||
|
||||
(_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
|
||||
_operators[tokenHolder][operator];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-authorizeOperator}.
|
||||
*/
|
||||
function authorizeOperator(address operator) public virtual override {
|
||||
require(_msgSender() != operator, "ERC777: authorizing self as operator");
|
||||
|
||||
if (_defaultOperators[operator]) {
|
||||
delete _revokedDefaultOperators[_msgSender()][operator];
|
||||
} else {
|
||||
_operators[_msgSender()][operator] = true;
|
||||
}
|
||||
|
||||
emit AuthorizedOperator(operator, _msgSender());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-revokeOperator}.
|
||||
*/
|
||||
function revokeOperator(address operator) public virtual override {
|
||||
require(operator != _msgSender(), "ERC777: revoking self as operator");
|
||||
|
||||
if (_defaultOperators[operator]) {
|
||||
_revokedDefaultOperators[_msgSender()][operator] = true;
|
||||
} else {
|
||||
delete _operators[_msgSender()][operator];
|
||||
}
|
||||
|
||||
emit RevokedOperator(operator, _msgSender());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-defaultOperators}.
|
||||
*/
|
||||
function defaultOperators() public view virtual override returns (address[] memory) {
|
||||
return _defaultOperatorsArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-operatorSend}.
|
||||
*
|
||||
* Emits {Sent} and {IERC20-Transfer} events.
|
||||
*/
|
||||
function operatorSend(
|
||||
address sender,
|
||||
address recipient,
|
||||
uint256 amount,
|
||||
bytes memory data,
|
||||
bytes memory operatorData
|
||||
) public virtual override {
|
||||
require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
|
||||
_send(sender, recipient, amount, data, operatorData, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC777-operatorBurn}.
|
||||
*
|
||||
* Emits {Burned} and {IERC20-Transfer} events.
|
||||
*/
|
||||
function operatorBurn(
|
||||
address account,
|
||||
uint256 amount,
|
||||
bytes memory data,
|
||||
bytes memory operatorData
|
||||
) public virtual override {
|
||||
require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
|
||||
_burn(account, amount, data, operatorData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function allowance(address holder, address spender) public view virtual override returns (uint256) {
|
||||
return _allowances[holder][spender];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-approve}.
|
||||
*
|
||||
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
|
||||
* `transferFrom`. This is semantically equivalent to an infinite approval.
|
||||
*
|
||||
* Note that accounts cannot have allowance issued by their operators.
|
||||
*/
|
||||
function approve(address spender, uint256 value) public virtual override returns (bool) {
|
||||
address holder = _msgSender();
|
||||
_approve(holder, spender, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-transferFrom}.
|
||||
*
|
||||
* NOTE: Does not update the allowance if the current allowance
|
||||
* is the maximum `uint256`.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {
|
||||
address spender = _msgSender();
|
||||
_spendAllowance(holder, spender, amount);
|
||||
_send(holder, recipient, amount, "", "", false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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 the caller address as the `operator` and with
|
||||
* `userData` 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.
|
||||
*/
|
||||
function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {
|
||||
_mint(account, amount, userData, operatorData, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Creates `amount` tokens and assigns them to `account`, increasing
|
||||
* the total supply.
|
||||
*
|
||||
* If `requireReceptionAck` is set to true, and 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.
|
||||
*/
|
||||
function _mint(
|
||||
address account,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData,
|
||||
bool requireReceptionAck
|
||||
) internal virtual {
|
||||
require(account != address(0), "ERC777: mint to the zero address");
|
||||
|
||||
address operator = _msgSender();
|
||||
|
||||
_beforeTokenTransfer(operator, address(0), account, amount);
|
||||
|
||||
// Update state variables
|
||||
_totalSupply += amount;
|
||||
_balances[account] += amount;
|
||||
|
||||
_callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);
|
||||
|
||||
emit Minted(operator, account, amount, userData, operatorData);
|
||||
emit Transfer(address(0), account, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Send tokens
|
||||
* @param from address token holder address
|
||||
* @param to address recipient address
|
||||
* @param amount uint256 amount of tokens to transfer
|
||||
* @param userData bytes extra information provided by the token holder (if any)
|
||||
* @param operatorData bytes extra information provided by the operator (if any)
|
||||
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
|
||||
*/
|
||||
function _send(
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData,
|
||||
bool requireReceptionAck
|
||||
) internal virtual {
|
||||
require(from != address(0), "ERC777: transfer from the zero address");
|
||||
require(to != address(0), "ERC777: transfer to the zero address");
|
||||
|
||||
address operator = _msgSender();
|
||||
|
||||
_callTokensToSend(operator, from, to, amount, userData, operatorData);
|
||||
|
||||
_move(operator, from, to, amount, userData, operatorData);
|
||||
|
||||
_callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Burn tokens
|
||||
* @param from address token holder address
|
||||
* @param amount uint256 amount of tokens to burn
|
||||
* @param data bytes extra information provided by the token holder
|
||||
* @param operatorData bytes extra information provided by the operator (if any)
|
||||
*/
|
||||
function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {
|
||||
require(from != address(0), "ERC777: burn from the zero address");
|
||||
|
||||
address operator = _msgSender();
|
||||
|
||||
_callTokensToSend(operator, from, address(0), amount, data, operatorData);
|
||||
|
||||
_beforeTokenTransfer(operator, from, address(0), amount);
|
||||
|
||||
// Update state variables
|
||||
uint256 fromBalance = _balances[from];
|
||||
require(fromBalance >= amount, "ERC777: burn amount exceeds balance");
|
||||
unchecked {
|
||||
_balances[from] = fromBalance - amount;
|
||||
}
|
||||
_totalSupply -= amount;
|
||||
|
||||
emit Burned(operator, from, amount, data, operatorData);
|
||||
emit Transfer(from, address(0), amount);
|
||||
}
|
||||
|
||||
function _move(
|
||||
address operator,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData
|
||||
) private {
|
||||
_beforeTokenTransfer(operator, from, to, amount);
|
||||
|
||||
uint256 fromBalance = _balances[from];
|
||||
require(fromBalance >= amount, "ERC777: transfer amount exceeds balance");
|
||||
unchecked {
|
||||
_balances[from] = fromBalance - amount;
|
||||
}
|
||||
_balances[to] += amount;
|
||||
|
||||
emit Sent(operator, from, to, amount, userData, operatorData);
|
||||
emit Transfer(from, to, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {ERC20-_approve}.
|
||||
*
|
||||
* Note that accounts cannot have allowance issued by their operators.
|
||||
*/
|
||||
function _approve(address holder, address spender, uint256 value) internal virtual {
|
||||
require(holder != address(0), "ERC777: approve from the zero address");
|
||||
require(spender != address(0), "ERC777: approve to the zero address");
|
||||
|
||||
_allowances[holder][spender] = value;
|
||||
emit Approval(holder, spender, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Call from.tokensToSend() if the interface is registered
|
||||
* @param operator address operator requesting the transfer
|
||||
* @param from address token holder address
|
||||
* @param to address recipient address
|
||||
* @param amount uint256 amount of tokens to transfer
|
||||
* @param userData bytes extra information provided by the token holder (if any)
|
||||
* @param operatorData bytes extra information provided by the operator (if any)
|
||||
*/
|
||||
function _callTokensToSend(
|
||||
address operator,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData
|
||||
) private {
|
||||
address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
|
||||
if (implementer != address(0)) {
|
||||
IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
|
||||
* tokensReceived() was not registered for the recipient
|
||||
* @param operator address operator requesting the transfer
|
||||
* @param from address token holder address
|
||||
* @param to address recipient address
|
||||
* @param amount uint256 amount of tokens to transfer
|
||||
* @param userData bytes extra information provided by the token holder (if any)
|
||||
* @param operatorData bytes extra information provided by the operator (if any)
|
||||
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
|
||||
*/
|
||||
function _callTokensReceived(
|
||||
address operator,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData,
|
||||
bool requireReceptionAck
|
||||
) private {
|
||||
address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
|
||||
if (implementer != address(0)) {
|
||||
IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
|
||||
} else if (requireReceptionAck) {
|
||||
require(
|
||||
to.code.length == 0,
|
||||
"ERC777: token recipient contract has no implementer for ERC777TokensRecipient"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
|
||||
*
|
||||
* Does not update the allowance amount in case of infinite allowance.
|
||||
* Revert if not enough allowance is available.
|
||||
*
|
||||
* Might emit an {IERC20-Approval} event.
|
||||
*/
|
||||
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
|
||||
uint256 currentAllowance = allowance(owner, spender);
|
||||
if (currentAllowance != type(uint256).max) {
|
||||
require(currentAllowance >= amount, "ERC777: insufficient allowance");
|
||||
unchecked {
|
||||
_approve(owner, spender, currentAllowance - amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Hook that is called before any token transfer. This includes
|
||||
* calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.
|
||||
*
|
||||
* Calling conditions:
|
||||
*
|
||||
* - when `from` and `to` are 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 xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
|
||||
*/
|
||||
function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}
|
||||
}
|
||||
@ -1,200 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC777/IERC777.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC777Token standard as defined in the EIP.
|
||||
*
|
||||
* This contract uses the
|
||||
* https://eips.ethereum.org/EIPS/eip-1820[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}.
|
||||
*/
|
||||
interface IERC777 {
|
||||
/**
|
||||
* @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.
|
||||
*
|
||||
* Note that some additional user `data` and `operatorData` can be logged in the event.
|
||||
*/
|
||||
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `operator` destroys `amount` tokens from `account`.
|
||||
*
|
||||
* Note that some additional user `data` and `operatorData` can be logged in the event.
|
||||
*/
|
||||
event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `operator` is made operator for `tokenHolder`.
|
||||
*/
|
||||
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.
|
||||
*/
|
||||
event RevokedOperator(address indexed operator, address indexed tokenHolder);
|
||||
|
||||
/**
|
||||
* @dev Returns the name of the token.
|
||||
*/
|
||||
function name() external view returns (string memory);
|
||||
|
||||
/**
|
||||
* @dev Returns the symbol of the token, usually a shorter version of the
|
||||
* name.
|
||||
*/
|
||||
function symbol() external view returns (string memory);
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function granularity() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the amount of tokens in existence.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the amount of tokens owned by an account (`owner`).
|
||||
*/
|
||||
function balanceOf(address owner) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function send(address recipient, uint256 amount, bytes calldata data) external;
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function burn(uint256 amount, bytes calldata data) external;
|
||||
|
||||
/**
|
||||
* @dev 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}.
|
||||
*/
|
||||
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Make an account an operator of the caller.
|
||||
*
|
||||
* See {isOperatorFor}.
|
||||
*
|
||||
* Emits an {AuthorizedOperator} event.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `operator` cannot be calling address.
|
||||
*/
|
||||
function authorizeOperator(address operator) external;
|
||||
|
||||
/**
|
||||
* @dev Revoke an account's operator status for the caller.
|
||||
*
|
||||
* See {isOperatorFor} and {defaultOperators}.
|
||||
*
|
||||
* Emits a {RevokedOperator} event.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `operator` cannot be calling address.
|
||||
*/
|
||||
function revokeOperator(address operator) external;
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function defaultOperators() external view returns (address[] memory);
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function operatorSend(
|
||||
address sender,
|
||||
address recipient,
|
||||
uint256 amount,
|
||||
bytes calldata data,
|
||||
bytes calldata operatorData
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev 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`.
|
||||
*/
|
||||
function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
|
||||
|
||||
event Sent(
|
||||
address indexed operator,
|
||||
address indexed from,
|
||||
address indexed to,
|
||||
uint256 amount,
|
||||
bytes data,
|
||||
bytes operatorData
|
||||
);
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @dev 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
|
||||
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
|
||||
*
|
||||
* See {IERC1820Registry} and {ERC1820Implementer}.
|
||||
*/
|
||||
interface IERC777Recipient {
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function tokensReceived(
|
||||
address operator,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata userData,
|
||||
bytes calldata operatorData
|
||||
) external;
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @dev 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
|
||||
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
|
||||
*
|
||||
* See {IERC1820Registry} and {ERC1820Implementer}.
|
||||
*/
|
||||
interface IERC777Sender {
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function tokensToSend(
|
||||
address operator,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata userData,
|
||||
bytes calldata operatorData
|
||||
) external;
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
= ERC 777
|
||||
|
||||
[.readme-notice]
|
||||
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc777
|
||||
|
||||
CAUTION: As of v4.9, OpenZeppelin's implementation of ERC-777 is deprecated and will be removed in the next major release.
|
||||
|
||||
This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-777[ERC777 token standard].
|
||||
|
||||
TIP: For an overview of ERC777 tokens and a walk through on how to create a token contract read our xref:ROOT:erc777.adoc[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}}
|
||||
|
||||
{{ERC777}}
|
||||
|
||||
== Hooks
|
||||
|
||||
{{IERC777Sender}}
|
||||
|
||||
{{IERC777Recipient}}
|
||||
Reference in New Issue
Block a user