From 3c470e5d30f98e48dda99e4313647203f9887efa Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 8 Feb 2021 23:19:44 +0100 Subject: [PATCH 01/23] add an interface folder that lists common interfaces --- contracts/interfaces/ERC1155.sol | 7 ++ contracts/interfaces/ERC1271.sol | 8 ++ contracts/interfaces/ERC1363.sol | 123 +++++++++++++++++++++++++++++++ contracts/interfaces/ERC165.sol | 5 ++ contracts/interfaces/ERC173.sol | 19 +++++ contracts/interfaces/ERC1820.sol | 6 ++ contracts/interfaces/ERC20.sol | 5 ++ contracts/interfaces/ERC2612.sol | 7 ++ contracts/interfaces/ERC3156.sol | 58 +++++++++++++++ contracts/interfaces/ERC721.sol | 8 ++ contracts/interfaces/ERC725.sol | 13 ++++ contracts/interfaces/ERC777.sol | 7 ++ 12 files changed, 266 insertions(+) create mode 100644 contracts/interfaces/ERC1155.sol create mode 100644 contracts/interfaces/ERC1271.sol create mode 100644 contracts/interfaces/ERC1363.sol create mode 100644 contracts/interfaces/ERC165.sol create mode 100644 contracts/interfaces/ERC173.sol create mode 100644 contracts/interfaces/ERC1820.sol create mode 100644 contracts/interfaces/ERC20.sol create mode 100644 contracts/interfaces/ERC2612.sol create mode 100644 contracts/interfaces/ERC3156.sol create mode 100644 contracts/interfaces/ERC721.sol create mode 100644 contracts/interfaces/ERC725.sol create mode 100644 contracts/interfaces/ERC777.sol diff --git a/contracts/interfaces/ERC1155.sol b/contracts/interfaces/ERC1155.sol new file mode 100644 index 00000000000..77c8c70ff10 --- /dev/null +++ b/contracts/interfaces/ERC1155.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC1155/IERC1155.sol"; +import "../token/ERC1155/IERC1155MetadataURI.sol"; +import "../token/ERC1155/IERC1155Receiver.sol"; diff --git a/contracts/interfaces/ERC1271.sol b/contracts/interfaces/ERC1271.sol new file mode 100644 index 00000000000..53051b38331 --- /dev/null +++ b/contracts/interfaces/ERC1271.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface IERC1271 +{ + function isValidSignature(bytes calldata data, bytes calldata signature) external view returns (bytes4 magicValue); +} diff --git a/contracts/interfaces/ERC1363.sol b/contracts/interfaces/ERC1363.sol new file mode 100644 index 00000000000..471d2bb69fb --- /dev/null +++ b/contracts/interfaces/ERC1363.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC20/IERC20.sol"; +import "../introspection/IERC165.sol"; + +interface IERC1363 is IERC20, IERC165 { + /* + * Note: the ERC-165 identifier for this interface is 0x4bbee2df. + * 0x4bbee2df === + * bytes4(keccak256('transferAndCall(address,uint256)')) ^ + * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ + * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ + * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) + */ + + /* + * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce. + * 0xfb9ec8ce === + * bytes4(keccak256('approveAndCall(address,uint256)')) ^ + * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) + */ + + /** + * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @return true unless throwing + */ + function transferAndCall(address to, uint256 value) external returns (bool); + + /** + * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @param data bytes Additional data with no specified format, sent in call to `to` + * @return true unless throwing + */ + function transferAndCall(address to, uint256 value, bytes memory data) external returns (bool); + + /** + * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @return true unless throwing + */ + function transferFromAndCall(address from, address to, uint256 value) external returns (bool); + + + /** + * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @param data bytes Additional data with no specified format, sent in call to `to` + * @return true unless throwing + */ + function transferFromAndCall(address from, address to, uint256 value, bytes memory data) external returns (bool); + + /** + * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender + * and then call `onApprovalReceived` on spender. + * @param spender address The address which will spend the funds + * @param value uint256 The amount of tokens to be spent + */ + function approveAndCall(address spender, uint256 value) external returns (bool); + + /** + * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender + * and then call `onApprovalReceived` on spender. + * @param spender address The address which will spend the funds + * @param value uint256 The amount of tokens to be spent + * @param data bytes Additional data with no specified format, sent in call to `spender` + */ + function approveAndCall(address spender, uint256 value, bytes memory data) external returns (bool); +} + +interface IERC1363Receiver { + /* + * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. + * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) + */ + + /** + * @notice Handle the receipt of ERC1363 tokens + * @dev Any ERC1363 smart contract calls this function on the recipient + * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the + * transfer. Return of other than the magic value MUST result in the + * transaction being reverted. + * Note: the token contract address is always the message sender. + * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function + * @param from address The address which are token transferred from + * @param value uint256 The amount of tokens transferred + * @param data bytes Additional data with no specified format + * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` + * unless throwing + */ + function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4); +} + +interface IERC1363Spender { + /* + * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. + * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) + */ + + /** + * @notice Handle the approval of ERC1363 tokens + * @dev Any ERC1363 smart contract calls this function on the recipient + * after an `approve`. This function MAY throw to revert and reject the + * approval. Return of other than the magic value MUST result in the + * transaction being reverted. + * Note: the token contract address is always the message sender. + * @param owner address The address which called `approveAndCall` function + * @param value uint256 The amount of tokens to be spent + * @param data bytes Additional data with no specified format + * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` + * unless throwing + */ + function onApprovalReceived(address owner, uint256 value, bytes memory data) external returns (bytes4); +} diff --git a/contracts/interfaces/ERC165.sol b/contracts/interfaces/ERC165.sol new file mode 100644 index 00000000000..381a93926cc --- /dev/null +++ b/contracts/interfaces/ERC165.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../introspection/IERC165.sol"; diff --git a/contracts/interfaces/ERC173.sol b/contracts/interfaces/ERC173.sol new file mode 100644 index 00000000000..ea32a1cce04 --- /dev/null +++ b/contracts/interfaces/ERC173.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../introspection/IERC165.sol"; + +interface IERC173 is IERC165 { + /// @dev This emits when ownership of a contract changes. + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /// @notice Get the address of the owner + /// @return The address of the owner. + function owner() view external returns(address); + + /// @notice Set the address of the new owner of the contract + /// @dev Set _newOwner to address(0) to renounce any ownership. + /// @param _newOwner The address of the new owner of the contract + function transferOwnership(address _newOwner) external; +} diff --git a/contracts/interfaces/ERC1820.sol b/contracts/interfaces/ERC1820.sol new file mode 100644 index 00000000000..2b4fd352003 --- /dev/null +++ b/contracts/interfaces/ERC1820.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../introspection/IERC1820Implementer.sol"; +import "../introspection/IERC1820Registry.sol"; diff --git a/contracts/interfaces/ERC20.sol b/contracts/interfaces/ERC20.sol new file mode 100644 index 00000000000..0072add5e29 --- /dev/null +++ b/contracts/interfaces/ERC20.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC20/IERC20.sol"; diff --git a/contracts/interfaces/ERC2612.sol b/contracts/interfaces/ERC2612.sol new file mode 100644 index 00000000000..1bedd6165f1 --- /dev/null +++ b/contracts/interfaces/ERC2612.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../drafts/IERC20Permit.sol"; + +interface IERC2612 is IERC20Permit {} diff --git a/contracts/interfaces/ERC3156.sol b/contracts/interfaces/ERC3156.sol new file mode 100644 index 00000000000..e149145c8f2 --- /dev/null +++ b/contracts/interfaces/ERC3156.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface IERC3156FlashLender { + /** + * @dev The amount of currency available to be lent. + * @param token The loan currency. + * @return The amount of `token` that can be borrowed. + */ + function maxFlashLoan( + address token + ) external view returns (uint256); + + /** + * @dev The fee to be charged for a given loan. + * @param token The loan currency. + * @param amount The amount of tokens lent. + * @return The amount of `token` to be charged for the loan, on top of the returned principal. + */ + function flashFee( + address token, + uint256 amount + ) external view returns (uint256); + + /** + * @dev Initiate a flash loan. + * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. + * @param token The loan currency. + * @param amount The amount of tokens lent. + * @param data Arbitrary data structure, intended to contain user-defined parameters. + */ + function flashLoan( + address receiver, + address token, + uint256 amount, + bytes calldata data + ) external returns (bool); +} + +interface IERC3156FlashBorrower { + /** + * @dev Receive a flash loan. + * @param initiator The initiator of the loan. + * @param token The loan currency. + * @param amount The amount of tokens lent. + * @param fee The additional amount of tokens to repay. + * @param data Arbitrary data structure, intended to contain user-defined parameters. + * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" + */ + function onFlashLoan( + address initiator, + address token, + uint256 amount, + uint256 fee, + bytes calldata data + ) external returns (bytes32); +} diff --git a/contracts/interfaces/ERC721.sol b/contracts/interfaces/ERC721.sol new file mode 100644 index 00000000000..ea42ced18e6 --- /dev/null +++ b/contracts/interfaces/ERC721.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC721/IERC721.sol"; +import "../token/ERC721/IERC721Enumerable.sol"; +import "../token/ERC721/IERC721Metadata.sol"; +import "../token/ERC721/IERC721Receiver.sol"; diff --git a/contracts/interfaces/ERC725.sol b/contracts/interfaces/ERC725.sol new file mode 100644 index 00000000000..354afe693af --- /dev/null +++ b/contracts/interfaces/ERC725.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface IERC725 +{ + event DataChanged(bytes32 indexed key, bytes32 indexed value); + event ContractCreated(address indexed contractAddress); + + function getData(bytes32 key) external view returns (bytes32 value); + function setData(bytes32 key, bytes32 value) external; + function execute(uint256 operationType, address to, uint256 value, bytes calldata _data) external; +} diff --git a/contracts/interfaces/ERC777.sol b/contracts/interfaces/ERC777.sol new file mode 100644 index 00000000000..c0498eada20 --- /dev/null +++ b/contracts/interfaces/ERC777.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC777/IERC777.sol"; +import "../token/ERC777/IERC777Recipient.sol"; +import "../token/ERC777/IERC777Sender.sol"; From 1dc01419e463179fbfc6f600a2ec9e909a7fb0ea Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Fri, 12 Mar 2021 09:43:55 +0100 Subject: [PATCH 02/23] update interface folder for new 4.0 branch --- contracts/interfaces/ERC1155.sol | 2 +- contracts/interfaces/ERC1363.sol | 2 +- contracts/interfaces/ERC165.sol | 2 +- contracts/interfaces/ERC173.sol | 2 +- contracts/interfaces/ERC1820.sol | 4 ++-- contracts/interfaces/ERC20.sol | 1 + contracts/interfaces/ERC2612.sol | 2 +- contracts/interfaces/ERC721.sol | 4 ++-- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/contracts/interfaces/ERC1155.sol b/contracts/interfaces/ERC1155.sol index 77c8c70ff10..a6c38077651 100644 --- a/contracts/interfaces/ERC1155.sol +++ b/contracts/interfaces/ERC1155.sol @@ -3,5 +3,5 @@ pragma solidity ^0.8.0; import "../token/ERC1155/IERC1155.sol"; -import "../token/ERC1155/IERC1155MetadataURI.sol"; import "../token/ERC1155/IERC1155Receiver.sol"; +import "../token/ERC1155/extensions/IERC1155MetadataURI.sol"; diff --git a/contracts/interfaces/ERC1363.sol b/contracts/interfaces/ERC1363.sol index 471d2bb69fb..8350faf6e9d 100644 --- a/contracts/interfaces/ERC1363.sol +++ b/contracts/interfaces/ERC1363.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol"; -import "../introspection/IERC165.sol"; +import "../utils/introspection/IERC165.sol"; interface IERC1363 is IERC20, IERC165 { /* diff --git a/contracts/interfaces/ERC165.sol b/contracts/interfaces/ERC165.sol index 381a93926cc..e9f6b057ad8 100644 --- a/contracts/interfaces/ERC165.sol +++ b/contracts/interfaces/ERC165.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../introspection/IERC165.sol"; +import "../utils/introspection/IERC165.sol"; diff --git a/contracts/interfaces/ERC173.sol b/contracts/interfaces/ERC173.sol index ea32a1cce04..b982b900810 100644 --- a/contracts/interfaces/ERC173.sol +++ b/contracts/interfaces/ERC173.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; -import "../introspection/IERC165.sol"; +import "../utils/introspection/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. diff --git a/contracts/interfaces/ERC1820.sol b/contracts/interfaces/ERC1820.sol index 2b4fd352003..0be9158b68e 100644 --- a/contracts/interfaces/ERC1820.sol +++ b/contracts/interfaces/ERC1820.sol @@ -2,5 +2,5 @@ pragma solidity ^0.8.0; -import "../introspection/IERC1820Implementer.sol"; -import "../introspection/IERC1820Registry.sol"; +import "../utils/introspection/IERC1820Implementer.sol"; +import "../utils/introspection/IERC1820Registry.sol"; diff --git a/contracts/interfaces/ERC20.sol b/contracts/interfaces/ERC20.sol index 0072add5e29..43e195ce8a4 100644 --- a/contracts/interfaces/ERC20.sol +++ b/contracts/interfaces/ERC20.sol @@ -3,3 +3,4 @@ pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol"; +import "../token/ERC20/extensions/IERC20Metadata.sol"; diff --git a/contracts/interfaces/ERC2612.sol b/contracts/interfaces/ERC2612.sol index 1bedd6165f1..83a80ac93ff 100644 --- a/contracts/interfaces/ERC2612.sol +++ b/contracts/interfaces/ERC2612.sol @@ -2,6 +2,6 @@ pragma solidity ^0.8.0; -import "../drafts/IERC20Permit.sol"; +import "../token/ERC20/extensions/draft-IERC20Permit.sol"; interface IERC2612 is IERC20Permit {} diff --git a/contracts/interfaces/ERC721.sol b/contracts/interfaces/ERC721.sol index ea42ced18e6..445f70c6b74 100644 --- a/contracts/interfaces/ERC721.sol +++ b/contracts/interfaces/ERC721.sol @@ -3,6 +3,6 @@ pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol"; -import "../token/ERC721/IERC721Enumerable.sol"; -import "../token/ERC721/IERC721Metadata.sol"; import "../token/ERC721/IERC721Receiver.sol"; +import "../token/ERC721/extensions/IERC721Enumerable.sol"; +import "../token/ERC721/extensions/IERC721Metadata.sol"; From 7dac9c0b0427fccf358c72449256699b6f50d3ef Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Fri, 12 Mar 2021 10:08:50 +0100 Subject: [PATCH 03/23] rename interfaces files and add a documentation --- .../interfaces/{ERC1155.sol => IERC1155.sol} | 0 .../interfaces/{ERC1271.sol => IERC1271.sol} | 0 .../interfaces/{ERC1363.sol => IERC1363.sol} | 0 .../interfaces/{ERC165.sol => IERC165.sol} | 0 .../interfaces/{ERC173.sol => IERC173.sol} | 0 .../interfaces/{ERC1820.sol => IERC1820.sol} | 0 .../interfaces/{ERC20.sol => IERC20.sol} | 0 .../interfaces/{ERC2612.sol => IERC2612.sol} | 0 .../interfaces/{ERC3156.sol => IERC3156.sol} | 0 .../interfaces/{ERC721.sol => IERC721.sol} | 0 .../interfaces/{ERC725.sol => IERC725.sol} | 0 .../interfaces/{ERC777.sol => IERC777.sol} | 0 contracts/interfaces/README.adoc | 29 +++++++++++++++++++ 13 files changed, 29 insertions(+) rename contracts/interfaces/{ERC1155.sol => IERC1155.sol} (100%) rename contracts/interfaces/{ERC1271.sol => IERC1271.sol} (100%) rename contracts/interfaces/{ERC1363.sol => IERC1363.sol} (100%) rename contracts/interfaces/{ERC165.sol => IERC165.sol} (100%) rename contracts/interfaces/{ERC173.sol => IERC173.sol} (100%) rename contracts/interfaces/{ERC1820.sol => IERC1820.sol} (100%) rename contracts/interfaces/{ERC20.sol => IERC20.sol} (100%) rename contracts/interfaces/{ERC2612.sol => IERC2612.sol} (100%) rename contracts/interfaces/{ERC3156.sol => IERC3156.sol} (100%) rename contracts/interfaces/{ERC721.sol => IERC721.sol} (100%) rename contracts/interfaces/{ERC725.sol => IERC725.sol} (100%) rename contracts/interfaces/{ERC777.sol => IERC777.sol} (100%) create mode 100644 contracts/interfaces/README.adoc diff --git a/contracts/interfaces/ERC1155.sol b/contracts/interfaces/IERC1155.sol similarity index 100% rename from contracts/interfaces/ERC1155.sol rename to contracts/interfaces/IERC1155.sol diff --git a/contracts/interfaces/ERC1271.sol b/contracts/interfaces/IERC1271.sol similarity index 100% rename from contracts/interfaces/ERC1271.sol rename to contracts/interfaces/IERC1271.sol diff --git a/contracts/interfaces/ERC1363.sol b/contracts/interfaces/IERC1363.sol similarity index 100% rename from contracts/interfaces/ERC1363.sol rename to contracts/interfaces/IERC1363.sol diff --git a/contracts/interfaces/ERC165.sol b/contracts/interfaces/IERC165.sol similarity index 100% rename from contracts/interfaces/ERC165.sol rename to contracts/interfaces/IERC165.sol diff --git a/contracts/interfaces/ERC173.sol b/contracts/interfaces/IERC173.sol similarity index 100% rename from contracts/interfaces/ERC173.sol rename to contracts/interfaces/IERC173.sol diff --git a/contracts/interfaces/ERC1820.sol b/contracts/interfaces/IERC1820.sol similarity index 100% rename from contracts/interfaces/ERC1820.sol rename to contracts/interfaces/IERC1820.sol diff --git a/contracts/interfaces/ERC20.sol b/contracts/interfaces/IERC20.sol similarity index 100% rename from contracts/interfaces/ERC20.sol rename to contracts/interfaces/IERC20.sol diff --git a/contracts/interfaces/ERC2612.sol b/contracts/interfaces/IERC2612.sol similarity index 100% rename from contracts/interfaces/ERC2612.sol rename to contracts/interfaces/IERC2612.sol diff --git a/contracts/interfaces/ERC3156.sol b/contracts/interfaces/IERC3156.sol similarity index 100% rename from contracts/interfaces/ERC3156.sol rename to contracts/interfaces/IERC3156.sol diff --git a/contracts/interfaces/ERC721.sol b/contracts/interfaces/IERC721.sol similarity index 100% rename from contracts/interfaces/ERC721.sol rename to contracts/interfaces/IERC721.sol diff --git a/contracts/interfaces/ERC725.sol b/contracts/interfaces/IERC725.sol similarity index 100% rename from contracts/interfaces/ERC725.sol rename to contracts/interfaces/IERC725.sol diff --git a/contracts/interfaces/ERC777.sol b/contracts/interfaces/IERC777.sol similarity index 100% rename from contracts/interfaces/ERC777.sol rename to contracts/interfaces/IERC777.sol diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc new file mode 100644 index 00000000000..2b238918009 --- /dev/null +++ b/contracts/interfaces/README.adoc @@ -0,0 +1,29 @@ += Utilities + +[.readme-notice] +NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils + +List of standardized interfaces, usefull to interract with third party contracts that implement them. + +{{IERC20}} +{{IERC20Metadata}} +{{IERC165}} +{{IERC173}} +{{IERC721}} +{{IERC721Receiver}} +{{IERC721Enumerable}} +{{IERC721Metadata}} +{{IERC725}} +{{IERC777}} +{{IERC777Recipient}} +{{IERC777Sender}} +{{IERC1155}} +{{IERC1155Receiver}} +{{IERC1155MetadataURI}} +{{IERC1271}} +{{IERC1363}} +{{IERC1820Implementer}} +{{IERC1820Registry}} +{{IERC2612}} +{{IERC3156FlashLender}} +{{IERC3156FlashBorrower}} From 70c27688c1a5e09b993766b0e4039ce75d089836 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Fri, 12 Mar 2021 10:19:35 +0100 Subject: [PATCH 04/23] add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ff8a86584f..7ab363dbec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * `IERC20Metadata`: add a new extended interface that includes the optional `name()`, `symbol()` and `decimals()` functions. ([#2561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2561)) * `ERC777`: make reception acquirement optional in `_mint`. ([#2552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2552)) * `ERC20Permit`: add a `_useNonce` to enable further usage of ERC712 signatures. ([#2565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2565)) + * Add an `interface` folder containing solidity interfaces to final ERCs. ([#2517](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2517)) ## Unreleased From 91d283ae5d59c5e9de5d14df2a9dde69e7954ab5 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 17 May 2021 13:50:23 +0200 Subject: [PATCH 05/23] fix typo --- contracts/interfaces/IERC725.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/interfaces/IERC725.sol b/contracts/interfaces/IERC725.sol index 354afe693af..2309b7fb94a 100644 --- a/contracts/interfaces/IERC725.sol +++ b/contracts/interfaces/IERC725.sol @@ -2,8 +2,7 @@ pragma solidity ^0.8.0; -interface IERC725 -{ +interface IERC725 { event DataChanged(bytes32 indexed key, bytes32 indexed value); event ContractCreated(address indexed contractAddress); From 1ce731446b52f2c85e3e3ce127d2450acead1713 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 20 May 2021 10:31:56 +0200 Subject: [PATCH 06/23] move relevant interfaces to the interface folder --- contracts/interfaces/IERC1155.sol | 170 +++++++++++- contracts/interfaces/IERC1363.sol | 4 +- contracts/interfaces/IERC165.sol | 21 +- contracts/interfaces/IERC173.sol | 2 +- contracts/interfaces/IERC1820.sol | 125 ++++++++- contracts/interfaces/IERC20.sol | 92 ++++++- contracts/interfaces/IERC2612.sol | 48 +++- contracts/interfaces/IERC721.sol | 193 +++++++++++++- contracts/interfaces/IERC777.sol | 249 +++++++++++++++++- contracts/token/ERC1155/IERC1155.sol | 100 +------ contracts/token/ERC1155/IERC1155Receiver.sol | 54 +--- .../extensions/IERC1155MetadataURI.sol | 18 +- contracts/token/ERC20/IERC20.sol | 74 +----- .../token/ERC20/extensions/IERC20Metadata.sol | 24 +- .../ERC20/extensions/draft-IERC20Permit.sol | 48 +--- contracts/token/ERC721/IERC721.sol | 126 +-------- contracts/token/ERC721/IERC721Receiver.sol | 18 +- .../ERC721/extensions/IERC721Enumerable.sol | 26 +- .../ERC721/extensions/IERC721Metadata.sol | 24 +- contracts/token/ERC777/IERC777.sol | 185 +------------ contracts/token/ERC777/IERC777Recipient.sol | 31 +-- contracts/token/ERC777/IERC777Sender.sol | 31 +-- contracts/utils/introspection/IERC165.sol | 21 +- .../introspection/IERC1820Implementer.sol | 16 +- .../utils/introspection/IERC1820Registry.sol | 108 +------- 25 files changed, 901 insertions(+), 907 deletions(-) diff --git a/contracts/interfaces/IERC1155.sol b/contracts/interfaces/IERC1155.sol index a6c38077651..3f32467179e 100644 --- a/contracts/interfaces/IERC1155.sol +++ b/contracts/interfaces/IERC1155.sol @@ -2,6 +2,170 @@ pragma solidity ^0.8.0; -import "../token/ERC1155/IERC1155.sol"; -import "../token/ERC1155/IERC1155Receiver.sol"; -import "../token/ERC1155/extensions/IERC1155MetadataURI.sol"; +import "./IERC165.sol"; + +/** + * @dev Required interface of an ERC1155 compliant contract, as defined in the + * https://eips.ethereum.org/EIPS/eip-1155[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155 is IERC165 { + /** + * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. + */ + event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); + + /** + * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all + * transfers. + */ + event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); + + /** + * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to + * `approved`. + */ + event ApprovalForAll(address indexed account, address indexed operator, bool approved); + + /** + * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. + * + * If an {URI} event was emitted for `id`, the standard + * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value + * returned by {IERC1155MetadataURI-uri}. + */ + event URI(string value, uint256 indexed id); + + /** + * @dev Returns the amount of tokens of token type `id` owned by `account`. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function balanceOf(address account, uint256 id) external view returns (uint256); + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. + * + * Requirements: + * + * - `accounts` and `ids` must have the same length. + */ + function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); + + /** + * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, + * + * Emits an {ApprovalForAll} event. + * + * Requirements: + * + * - `operator` cannot be the caller. + */ + function setApprovalForAll(address operator, bool approved) external; + + /** + * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. + * + * See {setApprovalForAll}. + */ + function isApprovedForAll(address account, address operator) external view returns (bool); + + /** + * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. + * + * Emits a {TransferSingle} event. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. + * - `from` must have a balance of tokens of type `id` of at least `amount`. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the + * acceptance magic value. + */ + function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. + * + * Emits a {TransferBatch} event. + * + * Requirements: + * + * - `ids` and `amounts` must have the same length. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the + * acceptance magic value. + */ + function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; +} + +/** + * @dev _Available since v3.1._ + */ +interface IERC1155Receiver is IERC165 { + + /** + @dev Handles the receipt of a single ERC1155 token type. This function is + called at the end of a `safeTransferFrom` after the balance has been updated. + To accept the transfer, this must return + `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + (i.e. 0xf23a6e61, or its own function selector). + @param operator The address which initiated the transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param id The ID of the token being transferred + @param value The amount of tokens being transferred + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed + */ + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) + external + returns(bytes4); + + /** + @dev Handles the receipt of a multiple ERC1155 token types. This function + is called at the end of a `safeBatchTransferFrom` after the balances have + been updated. To accept the transfer(s), this must return + `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + (i.e. 0xbc197c81, or its own function selector). + @param operator The address which initiated the batch transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param ids An array containing ids of each token being transferred (order and length must match values array) + @param values An array containing amounts of each token being transferred (order and length must match ids array) + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed + */ + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) + external + returns(bytes4); +} + +/** + * @dev Interface of the optional ERC1155MetadataExtension interface, as defined + * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155MetadataURI is IERC1155 { + /** + * @dev Returns the URI for token type `id`. + * + * If the `\{id\}` substring is present in the URI, it must be replaced by + * clients with the actual token type ID. + */ + function uri(uint256 id) external view returns (string memory); +} diff --git a/contracts/interfaces/IERC1363.sol b/contracts/interfaces/IERC1363.sol index 8350faf6e9d..7bc8bc18683 100644 --- a/contracts/interfaces/IERC1363.sol +++ b/contracts/interfaces/IERC1363.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; -import "../token/ERC20/IERC20.sol"; -import "../utils/introspection/IERC165.sol"; +import "./IERC20.sol"; +import "./IERC165.sol"; interface IERC1363 is IERC20, IERC165 { /* diff --git a/contracts/interfaces/IERC165.sol b/contracts/interfaces/IERC165.sol index e9f6b057ad8..01c9c086491 100644 --- a/contracts/interfaces/IERC165.sol +++ b/contracts/interfaces/IERC165.sol @@ -2,4 +2,23 @@ pragma solidity ^0.8.0; -import "../utils/introspection/IERC165.sol"; +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/contracts/interfaces/IERC173.sol b/contracts/interfaces/IERC173.sol index b982b900810..3b99396fcf7 100644 --- a/contracts/interfaces/IERC173.sol +++ b/contracts/interfaces/IERC173.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; -import "../utils/introspection/IERC165.sol"; +import "./IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. diff --git a/contracts/interfaces/IERC1820.sol b/contracts/interfaces/IERC1820.sol index 0be9158b68e..39938d98770 100644 --- a/contracts/interfaces/IERC1820.sol +++ b/contracts/interfaces/IERC1820.sol @@ -2,5 +2,126 @@ pragma solidity ^0.8.0; -import "../utils/introspection/IERC1820Implementer.sol"; -import "../utils/introspection/IERC1820Registry.sol"; +/** + * @dev Interface for an ERC1820 implementer, as defined in the + * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. + * Used by contracts that will be registered as implementers in the + * {IERC1820Registry}. + */ +interface IERC1820Implementer { + /** + * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract + * implements `interfaceHash` for `account`. + * + * See {IERC1820Registry-setInterfaceImplementer}. + */ + function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); +} + +/** + * @dev Interface of the global ERC1820 Registry, as defined in the + * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register + * implementers for interfaces in this registry, as well as query support. + * + * Implementers may be shared by multiple accounts, and can also implement more + * than a single interface for each account. Contracts can implement interfaces + * for themselves, but externally-owned accounts (EOA) must delegate this to a + * contract. + * + * {IERC165} interfaces can also be queried via the registry. + * + * For an in-depth explanation and source code analysis, see the EIP text. + */ +interface IERC1820Registry { + /** + * @dev Sets `newManager` as the manager for `account`. A manager of an + * account is able to set interface implementers for it. + * + * By default, each account is its own manager. Passing a value of `0x0` in + * `newManager` will reset the manager to this initial state. + * + * Emits a {ManagerChanged} event. + * + * Requirements: + * + * - the caller must be the current manager for `account`. + */ + function setManager(address account, address newManager) external; + + /** + * @dev Returns the manager for `account`. + * + * See {setManager}. + */ + function getManager(address account) external view returns (address); + + /** + * @dev Sets the `implementer` contract as ``account``'s implementer for + * `interfaceHash`. + * + * `account` being the zero address is an alias for the caller's address. + * The zero address can also be used in `implementer` to remove an old one. + * + * See {interfaceHash} to learn how these are created. + * + * Emits an {InterfaceImplementerSet} event. + * + * Requirements: + * + * - the caller must be the current manager for `account`. + * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not + * end in 28 zeroes). + * - `implementer` must implement {IERC1820Implementer} and return true when + * queried for support, unless `implementer` is the caller. See + * {IERC1820Implementer-canImplementInterfaceForAddress}. + */ + function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external; + + /** + * @dev Returns the implementer of `interfaceHash` for `account`. If no such + * implementer is registered, returns the zero address. + * + * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 + * zeroes), `account` will be queried for support of it. + * + * `account` being the zero address is an alias for the caller's address. + */ + function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); + + /** + * @dev Returns the interface hash for an `interfaceName`, as defined in the + * corresponding + * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. + */ + function interfaceHash(string calldata interfaceName) external pure returns (bytes32); + + /** + * @notice Updates the cache with whether the contract implements an ERC165 interface or not. + * @param account Address of the contract for which to update the cache. + * @param interfaceId ERC165 interface for which to update the cache. + */ + function updateERC165Cache(address account, bytes4 interfaceId) external; + + /** + * @notice Checks whether a contract implements an ERC165 interface or not. + * If the result is not cached a direct lookup on the contract address is performed. + * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling + * {updateERC165Cache} with the contract address. + * @param account Address of the contract to check. + * @param interfaceId ERC165 interface to check. + * @return True if `account` implements `interfaceId`, false otherwise. + */ + function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); + + /** + * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. + * @param account Address of the contract to check. + * @param interfaceId ERC165 interface to check. + * @return True if `account` implements `interfaceId`, false otherwise. + */ + function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); + + event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); + + event ManagerChanged(address indexed account, address indexed newManager); +} diff --git a/contracts/interfaces/IERC20.sol b/contracts/interfaces/IERC20.sol index 43e195ce8a4..c4a02e7e5d8 100644 --- a/contracts/interfaces/IERC20.sol +++ b/contracts/interfaces/IERC20.sol @@ -2,5 +2,93 @@ pragma solidity ^0.8.0; -import "../token/ERC20/IERC20.sol"; -import "../token/ERC20/extensions/IERC20Metadata.sol"; +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} diff --git a/contracts/interfaces/IERC2612.sol b/contracts/interfaces/IERC2612.sol index 83a80ac93ff..be547fcadd3 100644 --- a/contracts/interfaces/IERC2612.sol +++ b/contracts/interfaces/IERC2612.sol @@ -2,6 +2,50 @@ pragma solidity ^0.8.0; -import "../token/ERC20/extensions/draft-IERC20Permit.sol"; +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +interface IERC2612 { + /** + * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, + * given ``owner``'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + */ + function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; -interface IERC2612 is IERC20Permit {} + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/contracts/interfaces/IERC721.sol b/contracts/interfaces/IERC721.sol index 445f70c6b74..7dfe106c95b 100644 --- a/contracts/interfaces/IERC721.sol +++ b/contracts/interfaces/IERC721.sol @@ -2,7 +2,192 @@ pragma solidity ^0.8.0; -import "../token/ERC721/IERC721.sol"; -import "../token/ERC721/IERC721Receiver.sol"; -import "../token/ERC721/extensions/IERC721Enumerable.sol"; -import "../token/ERC721/extensions/IERC721Metadata.sol"; +import "./IERC165.sol"; + +/** + * @dev Required interface of an ERC721 compliant contract. + */ +interface IERC721 is IERC165 { + /** + * @dev Emitted when `tokenId` token is transferred from `from` to `to`. + */ + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); + + /** + * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. + */ + event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); + + /** + * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + */ + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + /** + * @dev Returns the number of tokens in ``owner``'s account. + */ + function balanceOf(address owner) external view returns (uint256 balance); + + /** + * @dev Returns the owner of the `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function ownerOf(uint256 tokenId) external view returns (address owner); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) external; + + /** + * @dev Transfers `tokenId` token from `from` to `to`. + * + * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 tokenId) external; + + /** + * @dev Gives permission to `to` to transfer `tokenId` token to another account. + * The approval is cleared when the token is transferred. + * + * Only a single account can be approved at a time, so approving the zero address clears previous approvals. + * + * Requirements: + * + * - The caller must own the token or be an approved operator. + * - `tokenId` must exist. + * + * Emits an {Approval} event. + */ + function approve(address to, uint256 tokenId) external; + + /** + * @dev Returns the account approved for `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function getApproved(uint256 tokenId) external view returns (address operator); + + /** + * @dev Approve or remove `operator` as an operator for the caller. + * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + * + * Requirements: + * + * - The `operator` cannot be the caller. + * + * Emits an {ApprovalForAll} event. + */ + function setApprovalForAll(address operator, bool _approved) external; + + /** + * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. + * + * See {setApprovalForAll} + */ + function isApprovedForAll(address owner, address operator) external view returns (bool); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; +} + +/** + * @title ERC721 token receiver interface + * @dev Interface for any contract that wants to support safeTransfers + * from ERC721 asset contracts. + */ +interface IERC721Receiver { + /** + * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} + * by `operator` from `from`, this function is called. + * + * It must return its Solidity selector to confirm the token transfer. + * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. + * + * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. + */ + function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); +} + +/** + * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension + * @dev See https://eips.ethereum.org/EIPS/eip-721 + */ +interface IERC721Enumerable is IERC721 { + + /** + * @dev Returns the total amount of tokens stored by the contract. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns a token ID owned by `owner` at a given `index` of its token list. + * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); + + /** + * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. + * Use along with {totalSupply} to enumerate all tokens. + */ + function tokenByIndex(uint256 index) external view returns (uint256); +} + +/** + * @title ERC-721 Non-Fungible Token Standard, optional metadata extension + * @dev See https://eips.ethereum.org/EIPS/eip-721 + */ +interface IERC721Metadata is IERC721 { + + /** + * @dev Returns the token collection name. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the token collection symbol. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. + */ + function tokenURI(uint256 tokenId) external view returns (string memory); +} diff --git a/contracts/interfaces/IERC777.sol b/contracts/interfaces/IERC777.sol index c0498eada20..9eac636a353 100644 --- a/contracts/interfaces/IERC777.sol +++ b/contracts/interfaces/IERC777.sol @@ -2,6 +2,249 @@ pragma solidity ^0.8.0; -import "../token/ERC777/IERC777.sol"; -import "../token/ERC777/IERC777Recipient.sol"; -import "../token/ERC777/IERC777Sender.sol"; +/** + * @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 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 + ); + + 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); +} + +/** + * @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; +} + +/** + * @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; +} diff --git a/contracts/token/ERC1155/IERC1155.sol b/contracts/token/ERC1155/IERC1155.sol index 6335adf7a80..b37cde3a07e 100644 --- a/contracts/token/ERC1155/IERC1155.sol +++ b/contracts/token/ERC1155/IERC1155.sol @@ -2,102 +2,4 @@ pragma solidity ^0.8.0; -import "../../utils/introspection/IERC165.sol"; - -/** - * @dev Required interface of an ERC1155 compliant contract, as defined in the - * https://eips.ethereum.org/EIPS/eip-1155[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155 is IERC165 { - /** - * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. - */ - event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); - - /** - * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all - * transfers. - */ - event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); - - /** - * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to - * `approved`. - */ - event ApprovalForAll(address indexed account, address indexed operator, bool approved); - - /** - * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. - * - * If an {URI} event was emitted for `id`, the standard - * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value - * returned by {IERC1155MetadataURI-uri}. - */ - event URI(string value, uint256 indexed id); - - /** - * @dev Returns the amount of tokens of token type `id` owned by `account`. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function balanceOf(address account, uint256 id) external view returns (uint256); - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. - * - * Requirements: - * - * - `accounts` and `ids` must have the same length. - */ - function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); - - /** - * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, - * - * Emits an {ApprovalForAll} event. - * - * Requirements: - * - * - `operator` cannot be the caller. - */ - function setApprovalForAll(address operator, bool approved) external; - - /** - * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. - * - * See {setApprovalForAll}. - */ - function isApprovedForAll(address account, address operator) external view returns (bool); - - /** - * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. - * - `from` must have a balance of tokens of type `id` of at least `amount`. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; -} +import "../../interfaces/IERC1155.sol"; diff --git a/contracts/token/ERC1155/IERC1155Receiver.sol b/contracts/token/ERC1155/IERC1155Receiver.sol index 39a8b979a4b..b37cde3a07e 100644 --- a/contracts/token/ERC1155/IERC1155Receiver.sol +++ b/contracts/token/ERC1155/IERC1155Receiver.sol @@ -2,56 +2,4 @@ pragma solidity ^0.8.0; -import "../../utils/introspection/IERC165.sol"; - -/** - * @dev _Available since v3.1._ - */ -interface IERC1155Receiver is IERC165 { - - /** - @dev Handles the receipt of a single ERC1155 token type. This function is - called at the end of a `safeTransferFrom` after the balance has been updated. - To accept the transfer, this must return - `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` - (i.e. 0xf23a6e61, or its own function selector). - @param operator The address which initiated the transfer (i.e. msg.sender) - @param from The address which previously owned the token - @param id The ID of the token being transferred - @param value The amount of tokens being transferred - @param data Additional data with no specified format - @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed - */ - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) - external - returns(bytes4); - - /** - @dev Handles the receipt of a multiple ERC1155 token types. This function - is called at the end of a `safeBatchTransferFrom` after the balances have - been updated. To accept the transfer(s), this must return - `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` - (i.e. 0xbc197c81, or its own function selector). - @param operator The address which initiated the batch transfer (i.e. msg.sender) - @param from The address which previously owned the token - @param ids An array containing ids of each token being transferred (order and length must match values array) - @param values An array containing amounts of each token being transferred (order and length must match ids array) - @param data Additional data with no specified format - @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed - */ - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) - external - returns(bytes4); -} +import "../../interfaces/IERC1155.sol"; diff --git a/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol b/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol index df55d97bb11..6a3896d6fad 100644 --- a/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol +++ b/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol @@ -2,20 +2,4 @@ pragma solidity ^0.8.0; -import "../IERC1155.sol"; - -/** - * @dev Interface of the optional ERC1155MetadataExtension interface, as defined - * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155MetadataURI is IERC1155 { - /** - * @dev Returns the URI for token type `id`. - * - * If the `\{id\}` substring is present in the URI, it must be replaced by - * clients with the actual token type ID. - */ - function uri(uint256 id) external view returns (string memory); -} +import "../../../interfaces/IERC1155.sol"; diff --git a/contracts/token/ERC20/IERC20.sol b/contracts/token/ERC20/IERC20.sol index 1d0863fff6c..cd748354185 100644 --- a/contracts/token/ERC20/IERC20.sol +++ b/contracts/token/ERC20/IERC20.sol @@ -2,76 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20 { - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address recipient, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external view returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); - - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); -} +import "../../interfaces/IERC20.sol"; diff --git a/contracts/token/ERC20/extensions/IERC20Metadata.sol b/contracts/token/ERC20/extensions/IERC20Metadata.sol index 4fb868ae875..ebe710cb9b2 100644 --- a/contracts/token/ERC20/extensions/IERC20Metadata.sol +++ b/contracts/token/ERC20/extensions/IERC20Metadata.sol @@ -2,26 +2,4 @@ pragma solidity ^0.8.0; -import "../IERC20.sol"; - -/** - * @dev Interface for the optional metadata functions from the ERC20 standard. - * - * _Available since v4.1._ - */ -interface IERC20Metadata is IERC20 { - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the decimals places of the token. - */ - function decimals() external view returns (uint8); -} +import "../../../interfaces/IERC20.sol"; diff --git a/contracts/token/ERC20/extensions/draft-IERC20Permit.sol b/contracts/token/ERC20/extensions/draft-IERC20Permit.sol index 1a8731a5879..17f704d1999 100644 --- a/contracts/token/ERC20/extensions/draft-IERC20Permit.sol +++ b/contracts/token/ERC20/extensions/draft-IERC20Permit.sol @@ -2,50 +2,6 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by - * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. - */ -interface IERC20Permit { - /** - * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, - * given ``owner``'s signed approval. - * - * IMPORTANT: The same issues {IERC20-approve} has related to transaction - * ordering also apply here. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `deadline` must be a timestamp in the future. - * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` - * over the EIP712-formatted function arguments. - * - the signature must use ``owner``'s current nonce (see {nonces}). - * - * For more information on the signature format, see the - * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP - * section]. - */ - function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; +import "../../../interfaces/IERC2612.sol"; - /** - * @dev Returns the current nonce for `owner`. This value must be - * included whenever a signature is generated for {permit}. - * - * Every successful call to {permit} increases ``owner``'s nonce by one. This - * prevents a signature from being used multiple times. - */ - function nonces(address owner) external view returns (uint256); - - /** - * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32); -} +interface IERC20Permit is IERC2612 {} diff --git a/contracts/token/ERC721/IERC721.sol b/contracts/token/ERC721/IERC721.sol index 5811e7994ee..0ec93bace7e 100644 --- a/contracts/token/ERC721/IERC721.sol +++ b/contracts/token/ERC721/IERC721.sol @@ -2,128 +2,4 @@ pragma solidity ^0.8.0; -import "../../utils/introspection/IERC165.sol"; - -/** - * @dev Required interface of an ERC721 compliant contract. - */ -interface IERC721 is IERC165 { - /** - * @dev Emitted when `tokenId` token is transferred from `from` to `to`. - */ - event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. - */ - event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. - */ - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - /** - * @dev Returns the number of tokens in ``owner``'s account. - */ - function balanceOf(address owner) external view returns (uint256 balance); - - /** - * @dev Returns the owner of the `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function ownerOf(uint256 tokenId) external view returns (address owner); - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients - * are aware of the ERC721 protocol to prevent tokens from being forever locked. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) external; - - /** - * @dev Transfers `tokenId` token from `from` to `to`. - * - * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - * Emits a {Transfer} event. - */ - function transferFrom(address from, address to, uint256 tokenId) external; - - /** - * @dev Gives permission to `to` to transfer `tokenId` token to another account. - * The approval is cleared when the token is transferred. - * - * Only a single account can be approved at a time, so approving the zero address clears previous approvals. - * - * Requirements: - * - * - The caller must own the token or be an approved operator. - * - `tokenId` must exist. - * - * Emits an {Approval} event. - */ - function approve(address to, uint256 tokenId) external; - - /** - * @dev Returns the account approved for `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function getApproved(uint256 tokenId) external view returns (address operator); - - /** - * @dev Approve or remove `operator` as an operator for the caller. - * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. - * - * Requirements: - * - * - The `operator` cannot be the caller. - * - * Emits an {ApprovalForAll} event. - */ - function setApprovalForAll(address operator, bool _approved) external; - - /** - * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. - * - * See {setApprovalForAll} - */ - function isApprovedForAll(address owner, address operator) external view returns (bool); - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; -} +import "../../interfaces/IERC721.sol"; diff --git a/contracts/token/ERC721/IERC721Receiver.sol b/contracts/token/ERC721/IERC721Receiver.sol index 081f4ab8d83..0ec93bace7e 100644 --- a/contracts/token/ERC721/IERC721Receiver.sol +++ b/contracts/token/ERC721/IERC721Receiver.sol @@ -2,20 +2,4 @@ pragma solidity ^0.8.0; -/** - * @title ERC721 token receiver interface - * @dev Interface for any contract that wants to support safeTransfers - * from ERC721 asset contracts. - */ -interface IERC721Receiver { - /** - * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} - * by `operator` from `from`, this function is called. - * - * It must return its Solidity selector to confirm the token transfer. - * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. - * - * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. - */ - function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); -} +import "../../interfaces/IERC721.sol"; diff --git a/contracts/token/ERC721/extensions/IERC721Enumerable.sol b/contracts/token/ERC721/extensions/IERC721Enumerable.sol index 6cf0f83698d..f1eb79fc565 100644 --- a/contracts/token/ERC721/extensions/IERC721Enumerable.sol +++ b/contracts/token/ERC721/extensions/IERC721Enumerable.sol @@ -2,28 +2,4 @@ pragma solidity ^0.8.0; -import "../IERC721.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Enumerable is IERC721 { - - /** - * @dev Returns the total amount of tokens stored by the contract. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns a token ID owned by `owner` at a given `index` of its token list. - * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); - - /** - * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. - * Use along with {totalSupply} to enumerate all tokens. - */ - function tokenByIndex(uint256 index) external view returns (uint256); -} +import "../../../interfaces/IERC721.sol"; diff --git a/contracts/token/ERC721/extensions/IERC721Metadata.sol b/contracts/token/ERC721/extensions/IERC721Metadata.sol index 2379baca95a..f1eb79fc565 100644 --- a/contracts/token/ERC721/extensions/IERC721Metadata.sol +++ b/contracts/token/ERC721/extensions/IERC721Metadata.sol @@ -2,26 +2,4 @@ pragma solidity ^0.8.0; -import "../IERC721.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional metadata extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Metadata is IERC721 { - - /** - * @dev Returns the token collection name. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the token collection symbol. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. - */ - function tokenURI(uint256 tokenId) external view returns (string memory); -} +import "../../../interfaces/IERC721.sol"; diff --git a/contracts/token/ERC777/IERC777.sol b/contracts/token/ERC777/IERC777.sol index ad2beeb4cbf..746a358a787 100644 --- a/contracts/token/ERC777/IERC777.sol +++ b/contracts/token/ERC777/IERC777.sol @@ -2,187 +2,4 @@ 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 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 - ); - - 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); -} +import "../../interfaces/IERC777.sol"; diff --git a/contracts/token/ERC777/IERC777Recipient.sol b/contracts/token/ERC777/IERC777Recipient.sol index a8976915966..746a358a787 100644 --- a/contracts/token/ERC777/IERC777Recipient.sol +++ b/contracts/token/ERC777/IERC777Recipient.sol @@ -2,33 +2,4 @@ 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; -} +import "../../interfaces/IERC777.sol"; diff --git a/contracts/token/ERC777/IERC777Sender.sol b/contracts/token/ERC777/IERC777Sender.sol index 137181183df..746a358a787 100644 --- a/contracts/token/ERC777/IERC777Sender.sol +++ b/contracts/token/ERC777/IERC777Sender.sol @@ -2,33 +2,4 @@ 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; -} +import "../../interfaces/IERC777.sol"; diff --git a/contracts/utils/introspection/IERC165.sol b/contracts/utils/introspection/IERC165.sol index 01c9c086491..2c2f624b0d8 100644 --- a/contracts/utils/introspection/IERC165.sol +++ b/contracts/utils/introspection/IERC165.sol @@ -2,23 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the ERC165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[EIP]. - * - * Implementers can declare support of contract interfaces, which can then be - * queried by others ({ERC165Checker}). - * - * For an implementation, see {ERC165}. - */ -interface IERC165 { - /** - * @dev Returns true if this contract implements the interface defined by - * `interfaceId`. See the corresponding - * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] - * to learn more about how these ids are created. - * - * This function call must use less than 30 000 gas. - */ - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} +import "../../interfaces/IERC165.sol"; diff --git a/contracts/utils/introspection/IERC1820Implementer.sol b/contracts/utils/introspection/IERC1820Implementer.sol index a7c1ce0e523..61c81f52813 100644 --- a/contracts/utils/introspection/IERC1820Implementer.sol +++ b/contracts/utils/introspection/IERC1820Implementer.sol @@ -2,18 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface for an ERC1820 implementer, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. - * Used by contracts that will be registered as implementers in the - * {IERC1820Registry}. - */ -interface IERC1820Implementer { - /** - * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract - * implements `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); -} +import "../../interfaces/IERC1820.sol"; diff --git a/contracts/utils/introspection/IERC1820Registry.sol b/contracts/utils/introspection/IERC1820Registry.sol index 5ecd520a56f..61c81f52813 100644 --- a/contracts/utils/introspection/IERC1820Registry.sol +++ b/contracts/utils/introspection/IERC1820Registry.sol @@ -2,110 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the global ERC1820 Registry, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register - * implementers for interfaces in this registry, as well as query support. - * - * Implementers may be shared by multiple accounts, and can also implement more - * than a single interface for each account. Contracts can implement interfaces - * for themselves, but externally-owned accounts (EOA) must delegate this to a - * contract. - * - * {IERC165} interfaces can also be queried via the registry. - * - * For an in-depth explanation and source code analysis, see the EIP text. - */ -interface IERC1820Registry { - /** - * @dev Sets `newManager` as the manager for `account`. A manager of an - * account is able to set interface implementers for it. - * - * By default, each account is its own manager. Passing a value of `0x0` in - * `newManager` will reset the manager to this initial state. - * - * Emits a {ManagerChanged} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - */ - function setManager(address account, address newManager) external; - - /** - * @dev Returns the manager for `account`. - * - * See {setManager}. - */ - function getManager(address account) external view returns (address); - - /** - * @dev Sets the `implementer` contract as ``account``'s implementer for - * `interfaceHash`. - * - * `account` being the zero address is an alias for the caller's address. - * The zero address can also be used in `implementer` to remove an old one. - * - * See {interfaceHash} to learn how these are created. - * - * Emits an {InterfaceImplementerSet} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not - * end in 28 zeroes). - * - `implementer` must implement {IERC1820Implementer} and return true when - * queried for support, unless `implementer` is the caller. See - * {IERC1820Implementer-canImplementInterfaceForAddress}. - */ - function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external; - - /** - * @dev Returns the implementer of `interfaceHash` for `account`. If no such - * implementer is registered, returns the zero address. - * - * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 - * zeroes), `account` will be queried for support of it. - * - * `account` being the zero address is an alias for the caller's address. - */ - function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); - - /** - * @dev Returns the interface hash for an `interfaceName`, as defined in the - * corresponding - * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. - */ - function interfaceHash(string calldata interfaceName) external pure returns (bytes32); - - /** - * @notice Updates the cache with whether the contract implements an ERC165 interface or not. - * @param account Address of the contract for which to update the cache. - * @param interfaceId ERC165 interface for which to update the cache. - */ - function updateERC165Cache(address account, bytes4 interfaceId) external; - - /** - * @notice Checks whether a contract implements an ERC165 interface or not. - * If the result is not cached a direct lookup on the contract address is performed. - * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling - * {updateERC165Cache} with the contract address. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); - - /** - * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); - - event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); - - event ManagerChanged(address indexed account, address indexed newManager); -} +import "../../interfaces/IERC1820.sol"; From 010771eb0fde245dcddd3a5f703f1b814e32f819 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 20 May 2021 17:33:48 +0200 Subject: [PATCH 07/23] split interfaces contracts --- contracts/access/AccessControl.sol | 39 +-------- contracts/access/AccessControlEnumerable.sol | 15 +--- contracts/access/IAccessControl.sol | 87 +++++++++++++++++++ contracts/access/IAccessControlEnumerable.sol | 30 +++++++ contracts/interfaces/IERC1155.sol | 68 --------------- contracts/interfaces/IERC1155MetadataURI.sol | 21 +++++ contracts/interfaces/IERC1155Receiver.sol | 57 ++++++++++++ contracts/interfaces/IERC1820Implementer.sol | 19 ++++ .../{IERC1820.sol => IERC1820Registry.sol} | 16 ---- contracts/interfaces/IERC20.sol | 17 ---- contracts/interfaces/IERC20Metadata.sol | 22 +++++ contracts/interfaces/IERC3156.sol | 66 +------------- .../interfaces/IERC3156FlashBorrower.sol | 28 ++++++ contracts/interfaces/IERC3156FlashLender.sol | 47 ++++++++++ contracts/interfaces/IERC721.sol | 64 -------------- contracts/interfaces/IERC721Enumerable.sol | 29 +++++++ contracts/interfaces/IERC721Metadata.sol | 27 ++++++ contracts/interfaces/IERC721Receiver.sol | 21 +++++ contracts/interfaces/IERC777.sol | 62 ------------- contracts/interfaces/IERC777Recipient.sol | 34 ++++++++ contracts/interfaces/IERC777Sender.sol | 34 ++++++++ contracts/token/ERC1155/IERC1155Receiver.sol | 2 +- .../extensions/IERC1155MetadataURI.sol | 2 +- .../token/ERC20/extensions/IERC20Metadata.sol | 2 +- contracts/token/ERC721/IERC721Receiver.sol | 2 +- .../ERC721/extensions/IERC721Enumerable.sol | 2 +- .../ERC721/extensions/IERC721Metadata.sol | 2 +- contracts/token/ERC777/IERC777Recipient.sol | 2 +- contracts/token/ERC777/IERC777Sender.sol | 2 +- .../introspection/IERC1820Implementer.sol | 2 +- .../utils/introspection/IERC1820Registry.sol | 2 +- 31 files changed, 473 insertions(+), 350 deletions(-) create mode 100644 contracts/access/IAccessControl.sol create mode 100644 contracts/access/IAccessControlEnumerable.sol create mode 100644 contracts/interfaces/IERC1155MetadataURI.sol create mode 100644 contracts/interfaces/IERC1155Receiver.sol create mode 100644 contracts/interfaces/IERC1820Implementer.sol rename contracts/interfaces/{IERC1820.sol => IERC1820Registry.sol} (88%) create mode 100644 contracts/interfaces/IERC20Metadata.sol create mode 100644 contracts/interfaces/IERC3156FlashBorrower.sol create mode 100644 contracts/interfaces/IERC3156FlashLender.sol create mode 100644 contracts/interfaces/IERC721Enumerable.sol create mode 100644 contracts/interfaces/IERC721Metadata.sol create mode 100644 contracts/interfaces/IERC721Receiver.sol create mode 100644 contracts/interfaces/IERC777Recipient.sol create mode 100644 contracts/interfaces/IERC777Sender.sol diff --git a/contracts/access/AccessControl.sol b/contracts/access/AccessControl.sol index cf62500f8af..d530a3d15a1 100644 --- a/contracts/access/AccessControl.sol +++ b/contracts/access/AccessControl.sol @@ -2,21 +2,11 @@ pragma solidity ^0.8.0; +import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; -/** - * @dev External interface of AccessControl declared to support ERC165 detection. - */ -interface IAccessControl { - function hasRole(bytes32 role, address account) external view returns (bool); - function getRoleAdmin(bytes32 role) external view returns (bytes32); - function grantRole(bytes32 role, address account) external; - function revokeRole(bytes32 role, address account) external; - function renounceRole(bytes32 role, address account) external; -} - /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role @@ -65,33 +55,6 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 { bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - /** - * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` - * - * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite - * {RoleAdminChanged} not being emitted signaling this. - * - * _Available since v3.1._ - */ - event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); - - /** - * @dev Emitted when `account` is granted `role`. - * - * `sender` is the account that originated the contract call, an admin role - * bearer except when using {_setupRole}. - */ - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Emitted when `account` is revoked `role`. - * - * `sender` is the account that originated the contract call: - * - if using `revokeRole`, it is the admin role bearer - * - if using `renounceRole`, it is the role bearer (i.e. `account`) - */ - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. diff --git a/contracts/access/AccessControlEnumerable.sol b/contracts/access/AccessControlEnumerable.sol index c1522aa1aaf..6614da7cbea 100644 --- a/contracts/access/AccessControlEnumerable.sol +++ b/contracts/access/AccessControlEnumerable.sol @@ -2,17 +2,10 @@ pragma solidity ^0.8.0; +import "./IAccessControlEnumerable.sol"; import "./AccessControl.sol"; import "../utils/structs/EnumerableSet.sol"; -/** - * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. - */ -interface IAccessControlEnumerable { - function getRoleMember(bytes32 role, uint256 index) external view returns (address); - function getRoleMemberCount(bytes32 role) external view returns (uint256); -} - /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ @@ -56,7 +49,7 @@ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessCon /** * @dev Overload {grantRole} to track enumerable memberships */ - function grantRole(bytes32 role, address account) public virtual override { + function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { super.grantRole(role, account); _roleMembers[role].add(account); } @@ -64,7 +57,7 @@ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessCon /** * @dev Overload {revokeRole} to track enumerable memberships */ - function revokeRole(bytes32 role, address account) public virtual override { + function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { super.revokeRole(role, account); _roleMembers[role].remove(account); } @@ -72,7 +65,7 @@ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessCon /** * @dev Overload {renounceRole} to track enumerable memberships */ - function renounceRole(bytes32 role, address account) public virtual override { + function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { super.renounceRole(role, account); _roleMembers[role].remove(account); } diff --git a/contracts/access/IAccessControl.sol b/contracts/access/IAccessControl.sol new file mode 100644 index 00000000000..35325967308 --- /dev/null +++ b/contracts/access/IAccessControl.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev External interface of AccessControl declared to support ERC165 detection. + */ +interface IAccessControl { + /** + * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` + * + * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite + * {RoleAdminChanged} not being emitted signaling this. + * + * _Available since v3.1._ + */ + event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); + + /** + * @dev Emitted when `account` is granted `role`. + * + * `sender` is the account that originated the contract call, an admin role + * bearer except when using {_setupRole}. + */ + event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); + + /** + * @dev Emitted when `account` is revoked `role`. + * + * `sender` is the account that originated the contract call: + * - if using `revokeRole`, it is the admin role bearer + * - if using `renounceRole`, it is the role bearer (i.e. `account`) + */ + event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); + + /** + * @dev Returns `true` if `account` has been granted `role`. + */ + function hasRole(bytes32 role, address account) external view returns (bool); + + /** + * @dev Returns the admin role that controls `role`. See {grantRole} and + * {revokeRole}. + * + * To change a role's admin, use {_setRoleAdmin}. + */ + function getRoleAdmin(bytes32 role) external view returns (bytes32); + + /** + * @dev Grants `role` to `account`. + * + * If `account` had not been already granted `role`, emits a {RoleGranted} + * event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function grantRole(bytes32 role, address account) external; + + /** + * @dev Revokes `role` from `account`. + * + * If `account` had been granted `role`, emits a {RoleRevoked} event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function revokeRole(bytes32 role, address account) external; + + /** + * @dev Revokes `role` from the calling account. + * + * Roles are often managed via {grantRole} and {revokeRole}: this function's + * purpose is to provide a mechanism for accounts to lose their privileges + * if they are compromised (such as when a trusted device is misplaced). + * + * If the calling account had been granted `role`, emits a {RoleRevoked} + * event. + * + * Requirements: + * + * - the caller must be `account`. + */ + function renounceRole(bytes32 role, address account) external; +} diff --git a/contracts/access/IAccessControlEnumerable.sol b/contracts/access/IAccessControlEnumerable.sol new file mode 100644 index 00000000000..e4a8e9fba02 --- /dev/null +++ b/contracts/access/IAccessControlEnumerable.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IAccessControl.sol"; + +/** + * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. + */ +interface IAccessControlEnumerable is IAccessControl { + /** + * @dev Returns one of the accounts that have `role`. `index` must be a + * value between 0 and {getRoleMemberCount}, non-inclusive. + * + * Role bearers are not sorted in any particular way, and their ordering may + * change at any point. + * + * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure + * you perform all queries on the same block. See the following + * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] + * for more information. + */ + function getRoleMember(bytes32 role, uint256 index) external view returns (address); + + /** + * @dev Returns the number of accounts that have `role`. Can be used + * together with {getRoleMember} to enumerate all bearers of a role. + */ + function getRoleMemberCount(bytes32 role) external view returns (uint256); +} diff --git a/contracts/interfaces/IERC1155.sol b/contracts/interfaces/IERC1155.sol index 3f32467179e..f37b6ff16c9 100644 --- a/contracts/interfaces/IERC1155.sol +++ b/contracts/interfaces/IERC1155.sol @@ -101,71 +101,3 @@ interface IERC1155 is IERC165 { */ function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; } - -/** - * @dev _Available since v3.1._ - */ -interface IERC1155Receiver is IERC165 { - - /** - @dev Handles the receipt of a single ERC1155 token type. This function is - called at the end of a `safeTransferFrom` after the balance has been updated. - To accept the transfer, this must return - `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` - (i.e. 0xf23a6e61, or its own function selector). - @param operator The address which initiated the transfer (i.e. msg.sender) - @param from The address which previously owned the token - @param id The ID of the token being transferred - @param value The amount of tokens being transferred - @param data Additional data with no specified format - @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed - */ - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) - external - returns(bytes4); - - /** - @dev Handles the receipt of a multiple ERC1155 token types. This function - is called at the end of a `safeBatchTransferFrom` after the balances have - been updated. To accept the transfer(s), this must return - `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` - (i.e. 0xbc197c81, or its own function selector). - @param operator The address which initiated the batch transfer (i.e. msg.sender) - @param from The address which previously owned the token - @param ids An array containing ids of each token being transferred (order and length must match values array) - @param values An array containing amounts of each token being transferred (order and length must match ids array) - @param data Additional data with no specified format - @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed - */ - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) - external - returns(bytes4); -} - -/** - * @dev Interface of the optional ERC1155MetadataExtension interface, as defined - * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155MetadataURI is IERC1155 { - /** - * @dev Returns the URI for token type `id`. - * - * If the `\{id\}` substring is present in the URI, it must be replaced by - * clients with the actual token type ID. - */ - function uri(uint256 id) external view returns (string memory); -} diff --git a/contracts/interfaces/IERC1155MetadataURI.sol b/contracts/interfaces/IERC1155MetadataURI.sol new file mode 100644 index 00000000000..f636cc2d87a --- /dev/null +++ b/contracts/interfaces/IERC1155MetadataURI.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC1155.sol"; + +/** + * @dev Interface of the optional ERC1155MetadataExtension interface, as defined + * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155MetadataURI is IERC1155 { + /** + * @dev Returns the URI for token type `id`. + * + * If the `\{id\}` substring is present in the URI, it must be replaced by + * clients with the actual token type ID. + */ + function uri(uint256 id) external view returns (string memory); +} diff --git a/contracts/interfaces/IERC1155Receiver.sol b/contracts/interfaces/IERC1155Receiver.sol new file mode 100644 index 00000000000..c6d7a375ea2 --- /dev/null +++ b/contracts/interfaces/IERC1155Receiver.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC165.sol"; + +/** + * @dev _Available since v3.1._ + */ +interface IERC1155Receiver is IERC165 { + + /** + @dev Handles the receipt of a single ERC1155 token type. This function is + called at the end of a `safeTransferFrom` after the balance has been updated. + To accept the transfer, this must return + `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + (i.e. 0xf23a6e61, or its own function selector). + @param operator The address which initiated the transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param id The ID of the token being transferred + @param value The amount of tokens being transferred + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed + */ + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) + external + returns(bytes4); + + /** + @dev Handles the receipt of a multiple ERC1155 token types. This function + is called at the end of a `safeBatchTransferFrom` after the balances have + been updated. To accept the transfer(s), this must return + `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + (i.e. 0xbc197c81, or its own function selector). + @param operator The address which initiated the batch transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param ids An array containing ids of each token being transferred (order and length must match values array) + @param values An array containing amounts of each token being transferred (order and length must match ids array) + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed + */ + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) + external + returns(bytes4); +} diff --git a/contracts/interfaces/IERC1820Implementer.sol b/contracts/interfaces/IERC1820Implementer.sol new file mode 100644 index 00000000000..a7c1ce0e523 --- /dev/null +++ b/contracts/interfaces/IERC1820Implementer.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Interface for an ERC1820 implementer, as defined in the + * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. + * Used by contracts that will be registered as implementers in the + * {IERC1820Registry}. + */ +interface IERC1820Implementer { + /** + * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract + * implements `interfaceHash` for `account`. + * + * See {IERC1820Registry-setInterfaceImplementer}. + */ + function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); +} diff --git a/contracts/interfaces/IERC1820.sol b/contracts/interfaces/IERC1820Registry.sol similarity index 88% rename from contracts/interfaces/IERC1820.sol rename to contracts/interfaces/IERC1820Registry.sol index 39938d98770..5ecd520a56f 100644 --- a/contracts/interfaces/IERC1820.sol +++ b/contracts/interfaces/IERC1820Registry.sol @@ -2,22 +2,6 @@ pragma solidity ^0.8.0; -/** - * @dev Interface for an ERC1820 implementer, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. - * Used by contracts that will be registered as implementers in the - * {IERC1820Registry}. - */ -interface IERC1820Implementer { - /** - * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract - * implements `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); -} - /** * @dev Interface of the global ERC1820 Registry, as defined in the * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register diff --git a/contracts/interfaces/IERC20.sol b/contracts/interfaces/IERC20.sol index c4a02e7e5d8..1d0863fff6c 100644 --- a/contracts/interfaces/IERC20.sol +++ b/contracts/interfaces/IERC20.sol @@ -75,20 +75,3 @@ interface IERC20 { */ event Approval(address indexed owner, address indexed spender, uint256 value); } - -interface IERC20Metadata is IERC20 { - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the decimals places of the token. - */ - function decimals() external view returns (uint8); -} diff --git a/contracts/interfaces/IERC20Metadata.sol b/contracts/interfaces/IERC20Metadata.sol new file mode 100644 index 00000000000..fa3d6664bf7 --- /dev/null +++ b/contracts/interfaces/IERC20Metadata.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC20.sol"; + +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} diff --git a/contracts/interfaces/IERC3156.sol b/contracts/interfaces/IERC3156.sol index 4b0cb5547dd..36d64d5ec4d 100644 --- a/contracts/interfaces/IERC3156.sol +++ b/contracts/interfaces/IERC3156.sol @@ -2,67 +2,5 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the ERC3156 FlashBorrower, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * _Available since v4.1._ - */ -interface IERC3156FlashBorrower { - /** - * @dev Receive a flash loan. - * @param initiator The initiator of the loan. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @param fee The additional amount of tokens to repay. - * @param data Arbitrary data structure, intended to contain user-defined parameters. - * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" - */ - function onFlashLoan( - address initiator, - address token, - uint256 amount, - uint256 fee, - bytes calldata data - ) external returns (bytes32); -} - -/** - * @dev Interface of the ERC3156 FlashLender, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - */ -interface IERC3156FlashLender { - /** - * @dev The amount of currency available to be lended. - * @param token The loan currency. - * @return The amount of `token` that can be borrowed. - */ - function maxFlashLoan( - address token - ) external view returns (uint256); - - /** - * @dev The fee to be charged for a given loan. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @return The amount of `token` to be charged for the loan, on top of the returned principal. - */ - function flashFee( - address token, - uint256 amount - ) external view returns (uint256); - - /** - * @dev Initiate a flash loan. - * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @param data Arbitrary data structure, intended to contain user-defined parameters. - */ - function flashLoan( - IERC3156FlashBorrower receiver, - address token, - uint256 amount, - bytes calldata data - ) external returns (bool); - } +import "./IERC3156FlashBorrower.sol"; +import "./IERC3156FlashLender.sol"; diff --git a/contracts/interfaces/IERC3156FlashBorrower.sol b/contracts/interfaces/IERC3156FlashBorrower.sol new file mode 100644 index 00000000000..fb247468c88 --- /dev/null +++ b/contracts/interfaces/IERC3156FlashBorrower.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC3156 FlashBorrower, as defined in + * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. + * + * _Available since v4.1._ + */ +interface IERC3156FlashBorrower { + /** + * @dev Receive a flash loan. + * @param initiator The initiator of the loan. + * @param token The loan currency. + * @param amount The amount of tokens lent. + * @param fee The additional amount of tokens to repay. + * @param data Arbitrary data structure, intended to contain user-defined parameters. + * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" + */ + function onFlashLoan( + address initiator, + address token, + uint256 amount, + uint256 fee, + bytes calldata data + ) external returns (bytes32); +} diff --git a/contracts/interfaces/IERC3156FlashLender.sol b/contracts/interfaces/IERC3156FlashLender.sol new file mode 100644 index 00000000000..188f9316964 --- /dev/null +++ b/contracts/interfaces/IERC3156FlashLender.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC3156FlashBorrower.sol"; + +/** + * @dev Interface of the ERC3156 FlashLender, as defined in + * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. + * + * _Available since v4.1._ + */ +interface IERC3156FlashLender { + /** + * @dev The amount of currency available to be lended. + * @param token The loan currency. + * @return The amount of `token` that can be borrowed. + */ + function maxFlashLoan( + address token + ) external view returns (uint256); + + /** + * @dev The fee to be charged for a given loan. + * @param token The loan currency. + * @param amount The amount of tokens lent. + * @return The amount of `token` to be charged for the loan, on top of the returned principal. + */ + function flashFee( + address token, + uint256 amount + ) external view returns (uint256); + + /** + * @dev Initiate a flash loan. + * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. + * @param token The loan currency. + * @param amount The amount of tokens lent. + * @param data Arbitrary data structure, intended to contain user-defined parameters. + */ + function flashLoan( + IERC3156FlashBorrower receiver, + address token, + uint256 amount, + bytes calldata data + ) external returns (bool); + } diff --git a/contracts/interfaces/IERC721.sol b/contracts/interfaces/IERC721.sol index 7dfe106c95b..cb2c5197fd2 100644 --- a/contracts/interfaces/IERC721.sol +++ b/contracts/interfaces/IERC721.sol @@ -127,67 +127,3 @@ interface IERC721 is IERC165 { */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; } - -/** - * @title ERC721 token receiver interface - * @dev Interface for any contract that wants to support safeTransfers - * from ERC721 asset contracts. - */ -interface IERC721Receiver { - /** - * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} - * by `operator` from `from`, this function is called. - * - * It must return its Solidity selector to confirm the token transfer. - * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. - * - * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. - */ - function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); -} - -/** - * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Enumerable is IERC721 { - - /** - * @dev Returns the total amount of tokens stored by the contract. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns a token ID owned by `owner` at a given `index` of its token list. - * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); - - /** - * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. - * Use along with {totalSupply} to enumerate all tokens. - */ - function tokenByIndex(uint256 index) external view returns (uint256); -} - -/** - * @title ERC-721 Non-Fungible Token Standard, optional metadata extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Metadata is IERC721 { - - /** - * @dev Returns the token collection name. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the token collection symbol. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. - */ - function tokenURI(uint256 tokenId) external view returns (string memory); -} diff --git a/contracts/interfaces/IERC721Enumerable.sol b/contracts/interfaces/IERC721Enumerable.sol new file mode 100644 index 00000000000..2cb4789658a --- /dev/null +++ b/contracts/interfaces/IERC721Enumerable.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC721.sol"; + +/** + * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension + * @dev See https://eips.ethereum.org/EIPS/eip-721 + */ +interface IERC721Enumerable is IERC721 { + + /** + * @dev Returns the total amount of tokens stored by the contract. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns a token ID owned by `owner` at a given `index` of its token list. + * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); + + /** + * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. + * Use along with {totalSupply} to enumerate all tokens. + */ + function tokenByIndex(uint256 index) external view returns (uint256); +} diff --git a/contracts/interfaces/IERC721Metadata.sol b/contracts/interfaces/IERC721Metadata.sol new file mode 100644 index 00000000000..24f02f838ed --- /dev/null +++ b/contracts/interfaces/IERC721Metadata.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC721.sol"; + +/** + * @title ERC-721 Non-Fungible Token Standard, optional metadata extension + * @dev See https://eips.ethereum.org/EIPS/eip-721 + */ +interface IERC721Metadata is IERC721 { + + /** + * @dev Returns the token collection name. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the token collection symbol. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. + */ + function tokenURI(uint256 tokenId) external view returns (string memory); +} diff --git a/contracts/interfaces/IERC721Receiver.sol b/contracts/interfaces/IERC721Receiver.sol new file mode 100644 index 00000000000..081f4ab8d83 --- /dev/null +++ b/contracts/interfaces/IERC721Receiver.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @title ERC721 token receiver interface + * @dev Interface for any contract that wants to support safeTransfers + * from ERC721 asset contracts. + */ +interface IERC721Receiver { + /** + * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} + * by `operator` from `from`, this function is called. + * + * It must return its Solidity selector to confirm the token transfer. + * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. + * + * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. + */ + function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); +} diff --git a/contracts/interfaces/IERC777.sol b/contracts/interfaces/IERC777.sol index 9eac636a353..ad2beeb4cbf 100644 --- a/contracts/interfaces/IERC777.sol +++ b/contracts/interfaces/IERC777.sol @@ -186,65 +186,3 @@ interface IERC777 { event RevokedOperator(address indexed operator, address indexed tokenHolder); } - -/** - * @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; -} - -/** - * @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; -} diff --git a/contracts/interfaces/IERC777Recipient.sol b/contracts/interfaces/IERC777Recipient.sol new file mode 100644 index 00000000000..a8976915966 --- /dev/null +++ b/contracts/interfaces/IERC777Recipient.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT + +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; +} diff --git a/contracts/interfaces/IERC777Sender.sol b/contracts/interfaces/IERC777Sender.sol new file mode 100644 index 00000000000..137181183df --- /dev/null +++ b/contracts/interfaces/IERC777Sender.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT + +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; +} diff --git a/contracts/token/ERC1155/IERC1155Receiver.sol b/contracts/token/ERC1155/IERC1155Receiver.sol index b37cde3a07e..2b920e32569 100644 --- a/contracts/token/ERC1155/IERC1155Receiver.sol +++ b/contracts/token/ERC1155/IERC1155Receiver.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1155.sol"; +import "../../interfaces/IERC1155Receiver.sol"; diff --git a/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol b/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol index 6a3896d6fad..6d88f1eb8f8 100644 --- a/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol +++ b/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC1155.sol"; +import "../../../interfaces/IERC1155MetadataURI.sol"; diff --git a/contracts/token/ERC20/extensions/IERC20Metadata.sol b/contracts/token/ERC20/extensions/IERC20Metadata.sol index ebe710cb9b2..aeaffd1ffaf 100644 --- a/contracts/token/ERC20/extensions/IERC20Metadata.sol +++ b/contracts/token/ERC20/extensions/IERC20Metadata.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC20.sol"; +import "../../../interfaces/IERC20Metadata.sol"; diff --git a/contracts/token/ERC721/IERC721Receiver.sol b/contracts/token/ERC721/IERC721Receiver.sol index 0ec93bace7e..3d0c6a9bdd3 100644 --- a/contracts/token/ERC721/IERC721Receiver.sol +++ b/contracts/token/ERC721/IERC721Receiver.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC721.sol"; +import "../../interfaces/IERC721Receiver.sol"; diff --git a/contracts/token/ERC721/extensions/IERC721Enumerable.sol b/contracts/token/ERC721/extensions/IERC721Enumerable.sol index f1eb79fc565..d8789a1a825 100644 --- a/contracts/token/ERC721/extensions/IERC721Enumerable.sol +++ b/contracts/token/ERC721/extensions/IERC721Enumerable.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC721.sol"; +import "../../../interfaces/IERC721Enumerable.sol"; diff --git a/contracts/token/ERC721/extensions/IERC721Metadata.sol b/contracts/token/ERC721/extensions/IERC721Metadata.sol index f1eb79fc565..a52e95ab8d9 100644 --- a/contracts/token/ERC721/extensions/IERC721Metadata.sol +++ b/contracts/token/ERC721/extensions/IERC721Metadata.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC721.sol"; +import "../../../interfaces/IERC721Metadata.sol"; diff --git a/contracts/token/ERC777/IERC777Recipient.sol b/contracts/token/ERC777/IERC777Recipient.sol index 746a358a787..53b03edc6f6 100644 --- a/contracts/token/ERC777/IERC777Recipient.sol +++ b/contracts/token/ERC777/IERC777Recipient.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC777.sol"; +import "../../interfaces/IERC777Recipient.sol"; diff --git a/contracts/token/ERC777/IERC777Sender.sol b/contracts/token/ERC777/IERC777Sender.sol index 746a358a787..84b09b708e8 100644 --- a/contracts/token/ERC777/IERC777Sender.sol +++ b/contracts/token/ERC777/IERC777Sender.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC777.sol"; +import "../../interfaces/IERC777Sender.sol"; diff --git a/contracts/utils/introspection/IERC1820Implementer.sol b/contracts/utils/introspection/IERC1820Implementer.sol index 61c81f52813..e430e67f391 100644 --- a/contracts/utils/introspection/IERC1820Implementer.sol +++ b/contracts/utils/introspection/IERC1820Implementer.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1820.sol"; +import "../../interfaces/IERC1820Implementer.sol"; diff --git a/contracts/utils/introspection/IERC1820Registry.sol b/contracts/utils/introspection/IERC1820Registry.sol index 61c81f52813..1e3d42b6893 100644 --- a/contracts/utils/introspection/IERC1820Registry.sol +++ b/contracts/utils/introspection/IERC1820Registry.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1820.sol"; +import "../../interfaces/IERC1820Registry.sol"; From b94af3d46c8f5af072601a6a82bcd42e02716da2 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 20 May 2021 17:39:00 +0200 Subject: [PATCH 08/23] further spliting interface contracts --- contracts/interfaces/IERC1363.sol | 45 ----------------------- contracts/interfaces/IERC1363Receiver.sol | 26 +++++++++++++ contracts/interfaces/IERC1363Spender.sol | 25 +++++++++++++ 3 files changed, 51 insertions(+), 45 deletions(-) create mode 100644 contracts/interfaces/IERC1363Receiver.sol create mode 100644 contracts/interfaces/IERC1363Spender.sol diff --git a/contracts/interfaces/IERC1363.sol b/contracts/interfaces/IERC1363.sol index 7bc8bc18683..bd28b5d126a 100644 --- a/contracts/interfaces/IERC1363.sol +++ b/contracts/interfaces/IERC1363.sol @@ -76,48 +76,3 @@ interface IERC1363 is IERC20, IERC165 { */ function approveAndCall(address spender, uint256 value, bytes memory data) external returns (bool); } - -interface IERC1363Receiver { - /* - * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. - * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) - */ - - /** - * @notice Handle the receipt of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function - * @param from address The address which are token transferred from - * @param value uint256 The amount of tokens transferred - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` - * unless throwing - */ - function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4); -} - -interface IERC1363Spender { - /* - * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. - * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) - */ - - /** - * @notice Handle the approval of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after an `approve`. This function MAY throw to revert and reject the - * approval. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param owner address The address which called `approveAndCall` function - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` - * unless throwing - */ - function onApprovalReceived(address owner, uint256 value, bytes memory data) external returns (bytes4); -} diff --git a/contracts/interfaces/IERC1363Receiver.sol b/contracts/interfaces/IERC1363Receiver.sol new file mode 100644 index 00000000000..25a15d22d09 --- /dev/null +++ b/contracts/interfaces/IERC1363Receiver.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface IERC1363Receiver { + /* + * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. + * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) + */ + + /** + * @notice Handle the receipt of ERC1363 tokens + * @dev Any ERC1363 smart contract calls this function on the recipient + * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the + * transfer. Return of other than the magic value MUST result in the + * transaction being reverted. + * Note: the token contract address is always the message sender. + * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function + * @param from address The address which are token transferred from + * @param value uint256 The amount of tokens transferred + * @param data bytes Additional data with no specified format + * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` + * unless throwing + */ + function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4); +} diff --git a/contracts/interfaces/IERC1363Spender.sol b/contracts/interfaces/IERC1363Spender.sol new file mode 100644 index 00000000000..ac6f703f305 --- /dev/null +++ b/contracts/interfaces/IERC1363Spender.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface IERC1363Spender { + /* + * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. + * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) + */ + + /** + * @notice Handle the approval of ERC1363 tokens + * @dev Any ERC1363 smart contract calls this function on the recipient + * after an `approve`. This function MAY throw to revert and reject the + * approval. Return of other than the magic value MUST result in the + * transaction being reverted. + * Note: the token contract address is always the message sender. + * @param owner address The address which called `approveAndCall` function + * @param value uint256 The amount of tokens to be spent + * @param data bytes Additional data with no specified format + * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` + * unless throwing + */ + function onApprovalReceived(address owner, uint256 value, bytes memory data) external returns (bytes4); +} From d8d401e673e27132b7e861ab3723051606c790c8 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 2 Aug 2021 12:21:49 +0200 Subject: [PATCH 09/23] make ownable inherit ERC173 --- contracts/access/Ownable.sol | 10 +++++----- contracts/interfaces/IERC173.sol | 4 +--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/contracts/access/Ownable.sol b/contracts/access/Ownable.sol index bdad22b22e3..67aad53c6ba 100644 --- a/contracts/access/Ownable.sol +++ b/contracts/access/Ownable.sol @@ -2,7 +2,9 @@ pragma solidity ^0.8.0; +import "../interfaces/IERC173.sol"; import "../utils/Context.sol"; + /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to @@ -15,11 +17,9 @@ import "../utils/Context.sol"; * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ -abstract contract Ownable is Context { +abstract contract Ownable is Context, IERC173 { address private _owner; - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - /** * @dev Initializes the contract setting the deployer as the initial owner. */ @@ -32,7 +32,7 @@ abstract contract Ownable is Context { /** * @dev Returns the address of the current owner. */ - function owner() public view virtual returns (address) { + function owner() public view virtual override returns (address) { return _owner; } @@ -60,7 +60,7 @@ abstract contract Ownable is Context { * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ - function transferOwnership(address newOwner) public virtual onlyOwner { + function transferOwnership(address newOwner) public virtual override onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; diff --git a/contracts/interfaces/IERC173.sol b/contracts/interfaces/IERC173.sol index 3b99396fcf7..e4b51519565 100644 --- a/contracts/interfaces/IERC173.sol +++ b/contracts/interfaces/IERC173.sol @@ -2,9 +2,7 @@ pragma solidity ^0.8.0; -import "./IERC165.sol"; - -interface IERC173 is IERC165 { +interface IERC173 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); From 73979625f7cd4e8d9583abb18a7a4ca7eaf1a202 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 4 Aug 2021 23:20:30 -0300 Subject: [PATCH 10/23] move interfaces back to original location --- contracts/interfaces/IERC1155.sol | 100 +-------- contracts/interfaces/IERC1155MetadataURI.sol | 18 +- contracts/interfaces/IERC1155Receiver.sol | 54 +---- contracts/interfaces/IERC165.sol | 21 +- contracts/interfaces/IERC1820Implementer.sol | 16 +- contracts/interfaces/IERC1820Registry.sol | 108 +--------- contracts/interfaces/IERC20.sol | 74 +------ contracts/interfaces/IERC20Metadata.sol | 19 +- contracts/interfaces/IERC2612.sol | 51 ----- contracts/interfaces/IERC721.sol | 126 +----------- contracts/interfaces/IERC721Enumerable.sol | 26 +-- contracts/interfaces/IERC721Metadata.sol | 24 +-- contracts/interfaces/IERC721Receiver.sol | 18 +- contracts/interfaces/IERC777.sol | 185 +---------------- contracts/interfaces/IERC777Recipient.sol | 31 +-- contracts/interfaces/IERC777Sender.sol | 31 +-- contracts/interfaces/draft-IERC2612.sol | 5 + contracts/token/ERC1155/IERC1155.sol | 121 ++++++++++- contracts/token/ERC1155/IERC1155Receiver.sol | 49 ++++- .../extensions/IERC1155MetadataURI.sol | 18 +- contracts/token/ERC20/IERC20.sol | 78 +++++++- .../token/ERC20/extensions/IERC20Metadata.sol | 24 ++- .../ERC20/extensions/draft-IERC20Permit.sol | 56 +++++- contracts/token/ERC721/IERC721.sol | 139 ++++++++++++- contracts/token/ERC721/IERC721Receiver.sol | 23 ++- .../ERC721/extensions/IERC721Enumerable.sol | 25 ++- .../ERC721/extensions/IERC721Metadata.sol | 23 ++- contracts/token/ERC777/IERC777.sol | 189 +++++++++++++++++- contracts/token/ERC777/IERC777Recipient.sol | 31 ++- contracts/token/ERC777/IERC777Sender.sol | 31 ++- contracts/utils/introspection/IERC165.sol | 21 +- .../introspection/IERC1820Implementer.sol | 16 +- .../utils/introspection/IERC1820Registry.sol | 112 ++++++++++- 33 files changed, 959 insertions(+), 904 deletions(-) delete mode 100644 contracts/interfaces/IERC2612.sol create mode 100644 contracts/interfaces/draft-IERC2612.sol diff --git a/contracts/interfaces/IERC1155.sol b/contracts/interfaces/IERC1155.sol index f37b6ff16c9..9522849a8a1 100644 --- a/contracts/interfaces/IERC1155.sol +++ b/contracts/interfaces/IERC1155.sol @@ -2,102 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC165.sol"; - -/** - * @dev Required interface of an ERC1155 compliant contract, as defined in the - * https://eips.ethereum.org/EIPS/eip-1155[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155 is IERC165 { - /** - * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. - */ - event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); - - /** - * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all - * transfers. - */ - event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); - - /** - * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to - * `approved`. - */ - event ApprovalForAll(address indexed account, address indexed operator, bool approved); - - /** - * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. - * - * If an {URI} event was emitted for `id`, the standard - * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value - * returned by {IERC1155MetadataURI-uri}. - */ - event URI(string value, uint256 indexed id); - - /** - * @dev Returns the amount of tokens of token type `id` owned by `account`. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function balanceOf(address account, uint256 id) external view returns (uint256); - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. - * - * Requirements: - * - * - `accounts` and `ids` must have the same length. - */ - function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); - - /** - * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, - * - * Emits an {ApprovalForAll} event. - * - * Requirements: - * - * - `operator` cannot be the caller. - */ - function setApprovalForAll(address operator, bool approved) external; - - /** - * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. - * - * See {setApprovalForAll}. - */ - function isApprovedForAll(address account, address operator) external view returns (bool); - - /** - * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. - * - `from` must have a balance of tokens of type `id` of at least `amount`. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; -} +import "../token/ERC1155/IERC1155.sol"; diff --git a/contracts/interfaces/IERC1155MetadataURI.sol b/contracts/interfaces/IERC1155MetadataURI.sol index f636cc2d87a..4c524e6f359 100644 --- a/contracts/interfaces/IERC1155MetadataURI.sol +++ b/contracts/interfaces/IERC1155MetadataURI.sol @@ -2,20 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC1155.sol"; - -/** - * @dev Interface of the optional ERC1155MetadataExtension interface, as defined - * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155MetadataURI is IERC1155 { - /** - * @dev Returns the URI for token type `id`. - * - * If the `\{id\}` substring is present in the URI, it must be replaced by - * clients with the actual token type ID. - */ - function uri(uint256 id) external view returns (string memory); -} +import "../token/ERC1155/IERC1155MetadataURI.sol"; diff --git a/contracts/interfaces/IERC1155Receiver.sol b/contracts/interfaces/IERC1155Receiver.sol index c6d7a375ea2..79941cf577f 100644 --- a/contracts/interfaces/IERC1155Receiver.sol +++ b/contracts/interfaces/IERC1155Receiver.sol @@ -2,56 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC165.sol"; - -/** - * @dev _Available since v3.1._ - */ -interface IERC1155Receiver is IERC165 { - - /** - @dev Handles the receipt of a single ERC1155 token type. This function is - called at the end of a `safeTransferFrom` after the balance has been updated. - To accept the transfer, this must return - `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` - (i.e. 0xf23a6e61, or its own function selector). - @param operator The address which initiated the transfer (i.e. msg.sender) - @param from The address which previously owned the token - @param id The ID of the token being transferred - @param value The amount of tokens being transferred - @param data Additional data with no specified format - @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed - */ - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) - external - returns(bytes4); - - /** - @dev Handles the receipt of a multiple ERC1155 token types. This function - is called at the end of a `safeBatchTransferFrom` after the balances have - been updated. To accept the transfer(s), this must return - `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` - (i.e. 0xbc197c81, or its own function selector). - @param operator The address which initiated the batch transfer (i.e. msg.sender) - @param from The address which previously owned the token - @param ids An array containing ids of each token being transferred (order and length must match values array) - @param values An array containing amounts of each token being transferred (order and length must match ids array) - @param data Additional data with no specified format - @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed - */ - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) - external - returns(bytes4); -} +import "../token/ERC1155/IERC1155Receiver.sol"; diff --git a/contracts/interfaces/IERC165.sol b/contracts/interfaces/IERC165.sol index 01c9c086491..e9f6b057ad8 100644 --- a/contracts/interfaces/IERC165.sol +++ b/contracts/interfaces/IERC165.sol @@ -2,23 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the ERC165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[EIP]. - * - * Implementers can declare support of contract interfaces, which can then be - * queried by others ({ERC165Checker}). - * - * For an implementation, see {ERC165}. - */ -interface IERC165 { - /** - * @dev Returns true if this contract implements the interface defined by - * `interfaceId`. See the corresponding - * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] - * to learn more about how these ids are created. - * - * This function call must use less than 30 000 gas. - */ - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} +import "../utils/introspection/IERC165.sol"; diff --git a/contracts/interfaces/IERC1820Implementer.sol b/contracts/interfaces/IERC1820Implementer.sol index a7c1ce0e523..ead56245a36 100644 --- a/contracts/interfaces/IERC1820Implementer.sol +++ b/contracts/interfaces/IERC1820Implementer.sol @@ -2,18 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface for an ERC1820 implementer, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. - * Used by contracts that will be registered as implementers in the - * {IERC1820Registry}. - */ -interface IERC1820Implementer { - /** - * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract - * implements `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); -} +import "../utils/introspection/IERC1820Implementer.sol"; diff --git a/contracts/interfaces/IERC1820Registry.sol b/contracts/interfaces/IERC1820Registry.sol index 5ecd520a56f..77341290bd8 100644 --- a/contracts/interfaces/IERC1820Registry.sol +++ b/contracts/interfaces/IERC1820Registry.sol @@ -2,110 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the global ERC1820 Registry, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register - * implementers for interfaces in this registry, as well as query support. - * - * Implementers may be shared by multiple accounts, and can also implement more - * than a single interface for each account. Contracts can implement interfaces - * for themselves, but externally-owned accounts (EOA) must delegate this to a - * contract. - * - * {IERC165} interfaces can also be queried via the registry. - * - * For an in-depth explanation and source code analysis, see the EIP text. - */ -interface IERC1820Registry { - /** - * @dev Sets `newManager` as the manager for `account`. A manager of an - * account is able to set interface implementers for it. - * - * By default, each account is its own manager. Passing a value of `0x0` in - * `newManager` will reset the manager to this initial state. - * - * Emits a {ManagerChanged} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - */ - function setManager(address account, address newManager) external; - - /** - * @dev Returns the manager for `account`. - * - * See {setManager}. - */ - function getManager(address account) external view returns (address); - - /** - * @dev Sets the `implementer` contract as ``account``'s implementer for - * `interfaceHash`. - * - * `account` being the zero address is an alias for the caller's address. - * The zero address can also be used in `implementer` to remove an old one. - * - * See {interfaceHash} to learn how these are created. - * - * Emits an {InterfaceImplementerSet} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not - * end in 28 zeroes). - * - `implementer` must implement {IERC1820Implementer} and return true when - * queried for support, unless `implementer` is the caller. See - * {IERC1820Implementer-canImplementInterfaceForAddress}. - */ - function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external; - - /** - * @dev Returns the implementer of `interfaceHash` for `account`. If no such - * implementer is registered, returns the zero address. - * - * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 - * zeroes), `account` will be queried for support of it. - * - * `account` being the zero address is an alias for the caller's address. - */ - function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); - - /** - * @dev Returns the interface hash for an `interfaceName`, as defined in the - * corresponding - * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. - */ - function interfaceHash(string calldata interfaceName) external pure returns (bytes32); - - /** - * @notice Updates the cache with whether the contract implements an ERC165 interface or not. - * @param account Address of the contract for which to update the cache. - * @param interfaceId ERC165 interface for which to update the cache. - */ - function updateERC165Cache(address account, bytes4 interfaceId) external; - - /** - * @notice Checks whether a contract implements an ERC165 interface or not. - * If the result is not cached a direct lookup on the contract address is performed. - * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling - * {updateERC165Cache} with the contract address. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); - - /** - * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); - - event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); - - event ManagerChanged(address indexed account, address indexed newManager); -} +import "../utils/introspection/IERC1820Registry.sol"; diff --git a/contracts/interfaces/IERC20.sol b/contracts/interfaces/IERC20.sol index 1d0863fff6c..0072add5e29 100644 --- a/contracts/interfaces/IERC20.sol +++ b/contracts/interfaces/IERC20.sol @@ -2,76 +2,4 @@ pragma solidity ^0.8.0; -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20 { - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address recipient, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external view returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); - - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); -} +import "../token/ERC20/IERC20.sol"; diff --git a/contracts/interfaces/IERC20Metadata.sol b/contracts/interfaces/IERC20Metadata.sol index fa3d6664bf7..8b72362908a 100644 --- a/contracts/interfaces/IERC20Metadata.sol +++ b/contracts/interfaces/IERC20Metadata.sol @@ -2,21 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC20.sol"; - -interface IERC20Metadata is IERC20 { - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the decimals places of the token. - */ - function decimals() external view returns (uint8); -} +import "../token/ERC20/extensions/IERC20Metadata.sol"; diff --git a/contracts/interfaces/IERC2612.sol b/contracts/interfaces/IERC2612.sol deleted file mode 100644 index be547fcadd3..00000000000 --- a/contracts/interfaces/IERC2612.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by - * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. - */ -interface IERC2612 { - /** - * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, - * given ``owner``'s signed approval. - * - * IMPORTANT: The same issues {IERC20-approve} has related to transaction - * ordering also apply here. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `deadline` must be a timestamp in the future. - * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` - * over the EIP712-formatted function arguments. - * - the signature must use ``owner``'s current nonce (see {nonces}). - * - * For more information on the signature format, see the - * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP - * section]. - */ - function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; - - /** - * @dev Returns the current nonce for `owner`. This value must be - * included whenever a signature is generated for {permit}. - * - * Every successful call to {permit} increases ``owner``'s nonce by one. This - * prevents a signature from being used multiple times. - */ - function nonces(address owner) external view returns (uint256); - - /** - * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32); -} diff --git a/contracts/interfaces/IERC721.sol b/contracts/interfaces/IERC721.sol index cb2c5197fd2..8e763e61fe0 100644 --- a/contracts/interfaces/IERC721.sol +++ b/contracts/interfaces/IERC721.sol @@ -2,128 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC165.sol"; - -/** - * @dev Required interface of an ERC721 compliant contract. - */ -interface IERC721 is IERC165 { - /** - * @dev Emitted when `tokenId` token is transferred from `from` to `to`. - */ - event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. - */ - event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. - */ - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - /** - * @dev Returns the number of tokens in ``owner``'s account. - */ - function balanceOf(address owner) external view returns (uint256 balance); - - /** - * @dev Returns the owner of the `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function ownerOf(uint256 tokenId) external view returns (address owner); - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients - * are aware of the ERC721 protocol to prevent tokens from being forever locked. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) external; - - /** - * @dev Transfers `tokenId` token from `from` to `to`. - * - * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - * Emits a {Transfer} event. - */ - function transferFrom(address from, address to, uint256 tokenId) external; - - /** - * @dev Gives permission to `to` to transfer `tokenId` token to another account. - * The approval is cleared when the token is transferred. - * - * Only a single account can be approved at a time, so approving the zero address clears previous approvals. - * - * Requirements: - * - * - The caller must own the token or be an approved operator. - * - `tokenId` must exist. - * - * Emits an {Approval} event. - */ - function approve(address to, uint256 tokenId) external; - - /** - * @dev Returns the account approved for `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function getApproved(uint256 tokenId) external view returns (address operator); - - /** - * @dev Approve or remove `operator` as an operator for the caller. - * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. - * - * Requirements: - * - * - The `operator` cannot be the caller. - * - * Emits an {ApprovalForAll} event. - */ - function setApprovalForAll(address operator, bool _approved) external; - - /** - * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. - * - * See {setApprovalForAll} - */ - function isApprovedForAll(address owner, address operator) external view returns (bool); - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; -} +import "../token/ERC721/IERC721.sol"; diff --git a/contracts/interfaces/IERC721Enumerable.sol b/contracts/interfaces/IERC721Enumerable.sol index 2cb4789658a..db01d877378 100644 --- a/contracts/interfaces/IERC721Enumerable.sol +++ b/contracts/interfaces/IERC721Enumerable.sol @@ -2,28 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC721.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Enumerable is IERC721 { - - /** - * @dev Returns the total amount of tokens stored by the contract. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns a token ID owned by `owner` at a given `index` of its token list. - * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); - - /** - * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. - * Use along with {totalSupply} to enumerate all tokens. - */ - function tokenByIndex(uint256 index) external view returns (uint256); -} +import "../token/ERC721/extensions/IERC721Enumerable.sol"; diff --git a/contracts/interfaces/IERC721Metadata.sol b/contracts/interfaces/IERC721Metadata.sol index 24f02f838ed..7265be01a88 100644 --- a/contracts/interfaces/IERC721Metadata.sol +++ b/contracts/interfaces/IERC721Metadata.sol @@ -2,26 +2,4 @@ pragma solidity ^0.8.0; -import "./IERC721.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional metadata extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Metadata is IERC721 { - - /** - * @dev Returns the token collection name. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the token collection symbol. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. - */ - function tokenURI(uint256 tokenId) external view returns (string memory); -} +import "../token/ERC721/extensions/IERC721Metadata.sol"; diff --git a/contracts/interfaces/IERC721Receiver.sol b/contracts/interfaces/IERC721Receiver.sol index 081f4ab8d83..e23d986be5c 100644 --- a/contracts/interfaces/IERC721Receiver.sol +++ b/contracts/interfaces/IERC721Receiver.sol @@ -2,20 +2,4 @@ pragma solidity ^0.8.0; -/** - * @title ERC721 token receiver interface - * @dev Interface for any contract that wants to support safeTransfers - * from ERC721 asset contracts. - */ -interface IERC721Receiver { - /** - * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} - * by `operator` from `from`, this function is called. - * - * It must return its Solidity selector to confirm the token transfer. - * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. - * - * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. - */ - function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); -} +import "../token/ERC721/IERC721Receiver.sol"; diff --git a/contracts/interfaces/IERC777.sol b/contracts/interfaces/IERC777.sol index ad2beeb4cbf..88f7792f3f3 100644 --- a/contracts/interfaces/IERC777.sol +++ b/contracts/interfaces/IERC777.sol @@ -2,187 +2,4 @@ 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 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 - ); - - 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); -} +import "../token/ERC777/IERC777.sol"; diff --git a/contracts/interfaces/IERC777Recipient.sol b/contracts/interfaces/IERC777Recipient.sol index a8976915966..23d7e7b005b 100644 --- a/contracts/interfaces/IERC777Recipient.sol +++ b/contracts/interfaces/IERC777Recipient.sol @@ -2,33 +2,4 @@ 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; -} +import "../token/ERC777/IERC777Recipient.sol"; diff --git a/contracts/interfaces/IERC777Sender.sol b/contracts/interfaces/IERC777Sender.sol index 137181183df..ffd3fec581c 100644 --- a/contracts/interfaces/IERC777Sender.sol +++ b/contracts/interfaces/IERC777Sender.sol @@ -2,33 +2,4 @@ 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; -} +import "../token/ERC777/IERC777Sender.sol"; diff --git a/contracts/interfaces/draft-IERC2612.sol b/contracts/interfaces/draft-IERC2612.sol new file mode 100644 index 00000000000..96bc0bab949 --- /dev/null +++ b/contracts/interfaces/draft-IERC2612.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC20/extensions/draft-IERC20Permit.sol"; diff --git a/contracts/token/ERC1155/IERC1155.sol b/contracts/token/ERC1155/IERC1155.sol index b37cde3a07e..39abed8eeef 100644 --- a/contracts/token/ERC1155/IERC1155.sol +++ b/contracts/token/ERC1155/IERC1155.sol @@ -2,4 +2,123 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1155.sol"; +import "../../utils/introspection/IERC165.sol"; + +/** + * @dev Required interface of an ERC1155 compliant contract, as defined in the + * https://eips.ethereum.org/EIPS/eip-1155[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155 is IERC165 { + /** + * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. + */ + event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); + + /** + * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all + * transfers. + */ + event TransferBatch( + address indexed operator, + address indexed from, + address indexed to, + uint256[] ids, + uint256[] values + ); + + /** + * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to + * `approved`. + */ + event ApprovalForAll(address indexed account, address indexed operator, bool approved); + + /** + * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. + * + * If an {URI} event was emitted for `id`, the standard + * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value + * returned by {IERC1155MetadataURI-uri}. + */ + event URI(string value, uint256 indexed id); + + /** + * @dev Returns the amount of tokens of token type `id` owned by `account`. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function balanceOf(address account, uint256 id) external view returns (uint256); + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. + * + * Requirements: + * + * - `accounts` and `ids` must have the same length. + */ + function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) + external + view + returns (uint256[] memory); + + /** + * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, + * + * Emits an {ApprovalForAll} event. + * + * Requirements: + * + * - `operator` cannot be the caller. + */ + function setApprovalForAll(address operator, bool approved) external; + + /** + * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. + * + * See {setApprovalForAll}. + */ + function isApprovedForAll(address account, address operator) external view returns (bool); + + /** + * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. + * + * Emits a {TransferSingle} event. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. + * - `from` must have a balance of tokens of type `id` of at least `amount`. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the + * acceptance magic value. + */ + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes calldata data + ) external; + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. + * + * Emits a {TransferBatch} event. + * + * Requirements: + * + * - `ids` and `amounts` must have the same length. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the + * acceptance magic value. + */ + function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data + ) external; +} diff --git a/contracts/token/ERC1155/IERC1155Receiver.sol b/contracts/token/ERC1155/IERC1155Receiver.sol index 2b920e32569..fe2a0590ffa 100644 --- a/contracts/token/ERC1155/IERC1155Receiver.sol +++ b/contracts/token/ERC1155/IERC1155Receiver.sol @@ -2,4 +2,51 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1155Receiver.sol"; +import "../../utils/introspection/IERC165.sol"; + +/** + * @dev _Available since v3.1._ + */ +interface IERC1155Receiver is IERC165 { + /** + @dev Handles the receipt of a single ERC1155 token type. This function is + called at the end of a `safeTransferFrom` after the balance has been updated. + To accept the transfer, this must return + `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + (i.e. 0xf23a6e61, or its own function selector). + @param operator The address which initiated the transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param id The ID of the token being transferred + @param value The amount of tokens being transferred + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed + */ + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) external returns (bytes4); + + /** + @dev Handles the receipt of a multiple ERC1155 token types. This function + is called at the end of a `safeBatchTransferFrom` after the balances have + been updated. To accept the transfer(s), this must return + `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + (i.e. 0xbc197c81, or its own function selector). + @param operator The address which initiated the batch transfer (i.e. msg.sender) + @param from The address which previously owned the token + @param ids An array containing ids of each token being transferred (order and length must match values array) + @param values An array containing amounts of each token being transferred (order and length must match ids array) + @param data Additional data with no specified format + @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed + */ + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) external returns (bytes4); +} diff --git a/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol b/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol index 6d88f1eb8f8..df55d97bb11 100644 --- a/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol +++ b/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol @@ -2,4 +2,20 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC1155MetadataURI.sol"; +import "../IERC1155.sol"; + +/** + * @dev Interface of the optional ERC1155MetadataExtension interface, as defined + * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155MetadataURI is IERC1155 { + /** + * @dev Returns the URI for token type `id`. + * + * If the `\{id\}` substring is present in the URI, it must be replaced by + * clients with the actual token type ID. + */ + function uri(uint256 id) external view returns (string memory); +} diff --git a/contracts/token/ERC20/IERC20.sol b/contracts/token/ERC20/IERC20.sol index cd748354185..08a04ad74bb 100644 --- a/contracts/token/ERC20/IERC20.sol +++ b/contracts/token/ERC20/IERC20.sol @@ -2,4 +2,80 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC20.sol"; +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external returns (bool); + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/contracts/token/ERC20/extensions/IERC20Metadata.sol b/contracts/token/ERC20/extensions/IERC20Metadata.sol index aeaffd1ffaf..4fb868ae875 100644 --- a/contracts/token/ERC20/extensions/IERC20Metadata.sol +++ b/contracts/token/ERC20/extensions/IERC20Metadata.sol @@ -2,4 +2,26 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC20Metadata.sol"; +import "../IERC20.sol"; + +/** + * @dev Interface for the optional metadata functions from the ERC20 standard. + * + * _Available since v4.1._ + */ +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} diff --git a/contracts/token/ERC20/extensions/draft-IERC20Permit.sol b/contracts/token/ERC20/extensions/draft-IERC20Permit.sol index 17f704d1999..33eb295ea2b 100644 --- a/contracts/token/ERC20/extensions/draft-IERC20Permit.sol +++ b/contracts/token/ERC20/extensions/draft-IERC20Permit.sol @@ -2,6 +2,58 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC2612.sol"; +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +interface IERC20Permit { + /** + * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, + * given ``owner``'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; -interface IERC20Permit is IERC2612 {} + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/contracts/token/ERC721/IERC721.sol b/contracts/token/ERC721/IERC721.sol index 0ec93bace7e..873ec6794b3 100644 --- a/contracts/token/ERC721/IERC721.sol +++ b/contracts/token/ERC721/IERC721.sol @@ -2,4 +2,141 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC721.sol"; +import "../../utils/introspection/IERC165.sol"; + +/** + * @dev Required interface of an ERC721 compliant contract. + */ +interface IERC721 is IERC165 { + /** + * @dev Emitted when `tokenId` token is transferred from `from` to `to`. + */ + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); + + /** + * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. + */ + event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); + + /** + * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + */ + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + /** + * @dev Returns the number of tokens in ``owner``'s account. + */ + function balanceOf(address owner) external view returns (uint256 balance); + + /** + * @dev Returns the owner of the `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function ownerOf(uint256 tokenId) external view returns (address owner); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) external; + + /** + * @dev Transfers `tokenId` token from `from` to `to`. + * + * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 tokenId + ) external; + + /** + * @dev Gives permission to `to` to transfer `tokenId` token to another account. + * The approval is cleared when the token is transferred. + * + * Only a single account can be approved at a time, so approving the zero address clears previous approvals. + * + * Requirements: + * + * - The caller must own the token or be an approved operator. + * - `tokenId` must exist. + * + * Emits an {Approval} event. + */ + function approve(address to, uint256 tokenId) external; + + /** + * @dev Returns the account approved for `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function getApproved(uint256 tokenId) external view returns (address operator); + + /** + * @dev Approve or remove `operator` as an operator for the caller. + * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + * + * Requirements: + * + * - The `operator` cannot be the caller. + * + * Emits an {ApprovalForAll} event. + */ + function setApprovalForAll(address operator, bool _approved) external; + + /** + * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. + * + * See {setApprovalForAll} + */ + function isApprovedForAll(address owner, address operator) external view returns (bool); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId, + bytes calldata data + ) external; +} diff --git a/contracts/token/ERC721/IERC721Receiver.sol b/contracts/token/ERC721/IERC721Receiver.sol index 3d0c6a9bdd3..9683f4a047d 100644 --- a/contracts/token/ERC721/IERC721Receiver.sol +++ b/contracts/token/ERC721/IERC721Receiver.sol @@ -2,4 +2,25 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC721Receiver.sol"; +/** + * @title ERC721 token receiver interface + * @dev Interface for any contract that wants to support safeTransfers + * from ERC721 asset contracts. + */ +interface IERC721Receiver { + /** + * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} + * by `operator` from `from`, this function is called. + * + * It must return its Solidity selector to confirm the token transfer. + * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. + * + * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. + */ + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external returns (bytes4); +} diff --git a/contracts/token/ERC721/extensions/IERC721Enumerable.sol b/contracts/token/ERC721/extensions/IERC721Enumerable.sol index d8789a1a825..c04295ba106 100644 --- a/contracts/token/ERC721/extensions/IERC721Enumerable.sol +++ b/contracts/token/ERC721/extensions/IERC721Enumerable.sol @@ -2,4 +2,27 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC721Enumerable.sol"; +import "../IERC721.sol"; + +/** + * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension + * @dev See https://eips.ethereum.org/EIPS/eip-721 + */ +interface IERC721Enumerable is IERC721 { + /** + * @dev Returns the total amount of tokens stored by the contract. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns a token ID owned by `owner` at a given `index` of its token list. + * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); + + /** + * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. + * Use along with {totalSupply} to enumerate all tokens. + */ + function tokenByIndex(uint256 index) external view returns (uint256); +} diff --git a/contracts/token/ERC721/extensions/IERC721Metadata.sol b/contracts/token/ERC721/extensions/IERC721Metadata.sol index a52e95ab8d9..cb9af003349 100644 --- a/contracts/token/ERC721/extensions/IERC721Metadata.sol +++ b/contracts/token/ERC721/extensions/IERC721Metadata.sol @@ -2,4 +2,25 @@ pragma solidity ^0.8.0; -import "../../../interfaces/IERC721Metadata.sol"; +import "../IERC721.sol"; + +/** + * @title ERC-721 Non-Fungible Token Standard, optional metadata extension + * @dev See https://eips.ethereum.org/EIPS/eip-721 + */ +interface IERC721Metadata is IERC721 { + /** + * @dev Returns the token collection name. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the token collection symbol. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. + */ + function tokenURI(uint256 tokenId) external view returns (string memory); +} diff --git a/contracts/token/ERC777/IERC777.sol b/contracts/token/ERC777/IERC777.sol index 746a358a787..c037d1a3215 100644 --- a/contracts/token/ERC777/IERC777.sol +++ b/contracts/token/ERC777/IERC777.sol @@ -2,4 +2,191 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC777.sol"; +/** + * @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 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 + ); + + 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); +} diff --git a/contracts/token/ERC777/IERC777Recipient.sol b/contracts/token/ERC777/IERC777Recipient.sol index 53b03edc6f6..a8976915966 100644 --- a/contracts/token/ERC777/IERC777Recipient.sol +++ b/contracts/token/ERC777/IERC777Recipient.sol @@ -2,4 +2,33 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC777Recipient.sol"; +/** + * @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; +} diff --git a/contracts/token/ERC777/IERC777Sender.sol b/contracts/token/ERC777/IERC777Sender.sol index 84b09b708e8..172f69eecab 100644 --- a/contracts/token/ERC777/IERC777Sender.sol +++ b/contracts/token/ERC777/IERC777Sender.sol @@ -2,4 +2,33 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC777Sender.sol"; +/** + * @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; +} diff --git a/contracts/utils/introspection/IERC165.sol b/contracts/utils/introspection/IERC165.sol index 2c2f624b0d8..01c9c086491 100644 --- a/contracts/utils/introspection/IERC165.sol +++ b/contracts/utils/introspection/IERC165.sol @@ -2,4 +2,23 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC165.sol"; +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/contracts/utils/introspection/IERC1820Implementer.sol b/contracts/utils/introspection/IERC1820Implementer.sol index e430e67f391..a7c1ce0e523 100644 --- a/contracts/utils/introspection/IERC1820Implementer.sol +++ b/contracts/utils/introspection/IERC1820Implementer.sol @@ -2,4 +2,18 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1820Implementer.sol"; +/** + * @dev Interface for an ERC1820 implementer, as defined in the + * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. + * Used by contracts that will be registered as implementers in the + * {IERC1820Registry}. + */ +interface IERC1820Implementer { + /** + * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract + * implements `interfaceHash` for `account`. + * + * See {IERC1820Registry-setInterfaceImplementer}. + */ + function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); +} diff --git a/contracts/utils/introspection/IERC1820Registry.sol b/contracts/utils/introspection/IERC1820Registry.sol index 1e3d42b6893..a93e37b9d2b 100644 --- a/contracts/utils/introspection/IERC1820Registry.sol +++ b/contracts/utils/introspection/IERC1820Registry.sol @@ -2,4 +2,114 @@ pragma solidity ^0.8.0; -import "../../interfaces/IERC1820Registry.sol"; +/** + * @dev Interface of the global ERC1820 Registry, as defined in the + * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register + * implementers for interfaces in this registry, as well as query support. + * + * Implementers may be shared by multiple accounts, and can also implement more + * than a single interface for each account. Contracts can implement interfaces + * for themselves, but externally-owned accounts (EOA) must delegate this to a + * contract. + * + * {IERC165} interfaces can also be queried via the registry. + * + * For an in-depth explanation and source code analysis, see the EIP text. + */ +interface IERC1820Registry { + /** + * @dev Sets `newManager` as the manager for `account`. A manager of an + * account is able to set interface implementers for it. + * + * By default, each account is its own manager. Passing a value of `0x0` in + * `newManager` will reset the manager to this initial state. + * + * Emits a {ManagerChanged} event. + * + * Requirements: + * + * - the caller must be the current manager for `account`. + */ + function setManager(address account, address newManager) external; + + /** + * @dev Returns the manager for `account`. + * + * See {setManager}. + */ + function getManager(address account) external view returns (address); + + /** + * @dev Sets the `implementer` contract as ``account``'s implementer for + * `interfaceHash`. + * + * `account` being the zero address is an alias for the caller's address. + * The zero address can also be used in `implementer` to remove an old one. + * + * See {interfaceHash} to learn how these are created. + * + * Emits an {InterfaceImplementerSet} event. + * + * Requirements: + * + * - the caller must be the current manager for `account`. + * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not + * end in 28 zeroes). + * - `implementer` must implement {IERC1820Implementer} and return true when + * queried for support, unless `implementer` is the caller. See + * {IERC1820Implementer-canImplementInterfaceForAddress}. + */ + function setInterfaceImplementer( + address account, + bytes32 _interfaceHash, + address implementer + ) external; + + /** + * @dev Returns the implementer of `interfaceHash` for `account`. If no such + * implementer is registered, returns the zero address. + * + * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 + * zeroes), `account` will be queried for support of it. + * + * `account` being the zero address is an alias for the caller's address. + */ + function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); + + /** + * @dev Returns the interface hash for an `interfaceName`, as defined in the + * corresponding + * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. + */ + function interfaceHash(string calldata interfaceName) external pure returns (bytes32); + + /** + * @notice Updates the cache with whether the contract implements an ERC165 interface or not. + * @param account Address of the contract for which to update the cache. + * @param interfaceId ERC165 interface for which to update the cache. + */ + function updateERC165Cache(address account, bytes4 interfaceId) external; + + /** + * @notice Checks whether a contract implements an ERC165 interface or not. + * If the result is not cached a direct lookup on the contract address is performed. + * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling + * {updateERC165Cache} with the contract address. + * @param account Address of the contract to check. + * @param interfaceId ERC165 interface to check. + * @return True if `account` implements `interfaceId`, false otherwise. + */ + function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); + + /** + * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. + * @param account Address of the contract to check. + * @param interfaceId ERC165 interface to check. + * @return True if `account` implements `interfaceId`, false otherwise. + */ + function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); + + event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); + + event ManagerChanged(address indexed account, address indexed newManager); +} From a5dbb3f210257825c3764bd03b69e34a794ef8f3 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 4 Aug 2021 23:25:10 -0300 Subject: [PATCH 11/23] fix bad import --- contracts/interfaces/IERC1155MetadataURI.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/interfaces/IERC1155MetadataURI.sol b/contracts/interfaces/IERC1155MetadataURI.sol index 4c524e6f359..2e10d3b8378 100644 --- a/contracts/interfaces/IERC1155MetadataURI.sol +++ b/contracts/interfaces/IERC1155MetadataURI.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.0; -import "../token/ERC1155/IERC1155MetadataURI.sol"; +import "../token/ERC1155/extensions/IERC1155MetadataURI.sol"; From 6fe7ba69bc3b7eabb4eef860d47ccfac73b192e4 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 15:30:21 +0200 Subject: [PATCH 12/23] Remove ERC173 --- contracts/access/Ownable.sol | 9 +++++---- contracts/interfaces/IERC173.sol | 17 ----------------- 2 files changed, 5 insertions(+), 21 deletions(-) delete mode 100644 contracts/interfaces/IERC173.sol diff --git a/contracts/access/Ownable.sol b/contracts/access/Ownable.sol index e59eec08936..16469d5a6bb 100644 --- a/contracts/access/Ownable.sol +++ b/contracts/access/Ownable.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.0; -import "../interfaces/IERC173.sol"; import "../utils/Context.sol"; /** @@ -17,9 +16,11 @@ import "../utils/Context.sol"; * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ -abstract contract Ownable is Context, IERC173 { +abstract contract Ownable is Context { address private _owner; + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + /** * @dev Initializes the contract setting the deployer as the initial owner. */ @@ -30,7 +31,7 @@ abstract contract Ownable is Context, IERC173 { /** * @dev Returns the address of the current owner. */ - function owner() public view virtual override returns (address) { + function owner() public view virtual returns (address) { return _owner; } @@ -57,7 +58,7 @@ abstract contract Ownable is Context, IERC173 { * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ - function transferOwnership(address newOwner) public virtual override onlyOwner { + function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } diff --git a/contracts/interfaces/IERC173.sol b/contracts/interfaces/IERC173.sol deleted file mode 100644 index e4b51519565..00000000000 --- a/contracts/interfaces/IERC173.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -interface IERC173 { - /// @dev This emits when ownership of a contract changes. - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /// @notice Get the address of the owner - /// @return The address of the owner. - function owner() view external returns(address); - - /// @notice Set the address of the new owner of the contract - /// @dev Set _newOwner to address(0) to renounce any ownership. - /// @param _newOwner The address of the new owner of the contract - function transferOwnership(address _newOwner) external; -} From 2acd00a1df83e07ea2d0358f06480dc6a0aeeba4 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 15:31:09 +0200 Subject: [PATCH 13/23] fix lint --- contracts/interfaces/IERC1363.sol | 140 +++++++++++-------- contracts/interfaces/IERC1363Receiver.sol | 43 +++--- contracts/interfaces/IERC1363Spender.sol | 40 +++--- contracts/interfaces/IERC3156FlashLender.sol | 11 +- contracts/interfaces/IERC725.sol | 9 +- 5 files changed, 135 insertions(+), 108 deletions(-) diff --git a/contracts/interfaces/IERC1363.sol b/contracts/interfaces/IERC1363.sol index bd28b5d126a..fca37847a65 100644 --- a/contracts/interfaces/IERC1363.sol +++ b/contracts/interfaces/IERC1363.sol @@ -6,73 +6,89 @@ import "./IERC20.sol"; import "./IERC165.sol"; interface IERC1363 is IERC20, IERC165 { - /* - * Note: the ERC-165 identifier for this interface is 0x4bbee2df. - * 0x4bbee2df === - * bytes4(keccak256('transferAndCall(address,uint256)')) ^ - * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) - */ + /* + * Note: the ERC-165 identifier for this interface is 0x4bbee2df. + * 0x4bbee2df === + * bytes4(keccak256('transferAndCall(address,uint256)')) ^ + * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ + * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ + * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) + */ - /* - * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce. - * 0xfb9ec8ce === - * bytes4(keccak256('approveAndCall(address,uint256)')) ^ - * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) - */ + /* + * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce. + * 0xfb9ec8ce === + * bytes4(keccak256('approveAndCall(address,uint256)')) ^ + * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) + */ - /** - * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @return true unless throwing - */ - function transferAndCall(address to, uint256 value) external returns (bool); + /** + * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @return true unless throwing + */ + function transferAndCall(address to, uint256 value) external returns (bool); - /** - * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @param data bytes Additional data with no specified format, sent in call to `to` - * @return true unless throwing - */ - function transferAndCall(address to, uint256 value, bytes memory data) external returns (bool); + /** + * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @param data bytes Additional data with no specified format, sent in call to `to` + * @return true unless throwing + */ + function transferAndCall( + address to, + uint256 value, + bytes memory data + ) external returns (bool); - /** - * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @return true unless throwing - */ - function transferFromAndCall(address from, address to, uint256 value) external returns (bool); + /** + * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @return true unless throwing + */ + function transferFromAndCall( + address from, + address to, + uint256 value + ) external returns (bool); + /** + * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 The amount of tokens to be transferred + * @param data bytes Additional data with no specified format, sent in call to `to` + * @return true unless throwing + */ + function transferFromAndCall( + address from, + address to, + uint256 value, + bytes memory data + ) external returns (bool); - /** - * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @param data bytes Additional data with no specified format, sent in call to `to` - * @return true unless throwing - */ - function transferFromAndCall(address from, address to, uint256 value, bytes memory data) external returns (bool); + /** + * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender + * and then call `onApprovalReceived` on spender. + * @param spender address The address which will spend the funds + * @param value uint256 The amount of tokens to be spent + */ + function approveAndCall(address spender, uint256 value) external returns (bool); - /** - * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender - * and then call `onApprovalReceived` on spender. - * @param spender address The address which will spend the funds - * @param value uint256 The amount of tokens to be spent - */ - function approveAndCall(address spender, uint256 value) external returns (bool); - - /** - * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender - * and then call `onApprovalReceived` on spender. - * @param spender address The address which will spend the funds - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format, sent in call to `spender` - */ - function approveAndCall(address spender, uint256 value, bytes memory data) external returns (bool); + /** + * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender + * and then call `onApprovalReceived` on spender. + * @param spender address The address which will spend the funds + * @param value uint256 The amount of tokens to be spent + * @param data bytes Additional data with no specified format, sent in call to `spender` + */ + function approveAndCall( + address spender, + uint256 value, + bytes memory data + ) external returns (bool); } diff --git a/contracts/interfaces/IERC1363Receiver.sol b/contracts/interfaces/IERC1363Receiver.sol index 25a15d22d09..1e9b3d49478 100644 --- a/contracts/interfaces/IERC1363Receiver.sol +++ b/contracts/interfaces/IERC1363Receiver.sol @@ -3,24 +3,29 @@ pragma solidity ^0.8.0; interface IERC1363Receiver { - /* - * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. - * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) - */ + /* + * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. + * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) + */ - /** - * @notice Handle the receipt of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function - * @param from address The address which are token transferred from - * @param value uint256 The amount of tokens transferred - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` - * unless throwing - */ - function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4); + /** + * @notice Handle the receipt of ERC1363 tokens + * @dev Any ERC1363 smart contract calls this function on the recipient + * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the + * transfer. Return of other than the magic value MUST result in the + * transaction being reverted. + * Note: the token contract address is always the message sender. + * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function + * @param from address The address which are token transferred from + * @param value uint256 The amount of tokens transferred + * @param data bytes Additional data with no specified format + * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` + * unless throwing + */ + function onTransferReceived( + address operator, + address from, + uint256 value, + bytes memory data + ) external returns (bytes4); } diff --git a/contracts/interfaces/IERC1363Spender.sol b/contracts/interfaces/IERC1363Spender.sol index ac6f703f305..fb58ffc6021 100644 --- a/contracts/interfaces/IERC1363Spender.sol +++ b/contracts/interfaces/IERC1363Spender.sol @@ -3,23 +3,27 @@ pragma solidity ^0.8.0; interface IERC1363Spender { - /* - * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. - * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) - */ + /* + * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. + * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) + */ - /** - * @notice Handle the approval of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after an `approve`. This function MAY throw to revert and reject the - * approval. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param owner address The address which called `approveAndCall` function - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` - * unless throwing - */ - function onApprovalReceived(address owner, uint256 value, bytes memory data) external returns (bytes4); + /** + * @notice Handle the approval of ERC1363 tokens + * @dev Any ERC1363 smart contract calls this function on the recipient + * after an `approve`. This function MAY throw to revert and reject the + * approval. Return of other than the magic value MUST result in the + * transaction being reverted. + * Note: the token contract address is always the message sender. + * @param owner address The address which called `approveAndCall` function + * @param value uint256 The amount of tokens to be spent + * @param data bytes Additional data with no specified format + * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` + * unless throwing + */ + function onApprovalReceived( + address owner, + uint256 value, + bytes memory data + ) external returns (bytes4); } diff --git a/contracts/interfaces/IERC3156FlashLender.sol b/contracts/interfaces/IERC3156FlashLender.sol index 188f9316964..8041ddbaccf 100644 --- a/contracts/interfaces/IERC3156FlashLender.sol +++ b/contracts/interfaces/IERC3156FlashLender.sol @@ -16,9 +16,7 @@ interface IERC3156FlashLender { * @param token The loan currency. * @return The amount of `token` that can be borrowed. */ - function maxFlashLoan( - address token - ) external view returns (uint256); + function maxFlashLoan(address token) external view returns (uint256); /** * @dev The fee to be charged for a given loan. @@ -26,10 +24,7 @@ interface IERC3156FlashLender { * @param amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ - function flashFee( - address token, - uint256 amount - ) external view returns (uint256); + function flashFee(address token, uint256 amount) external view returns (uint256); /** * @dev Initiate a flash loan. @@ -44,4 +39,4 @@ interface IERC3156FlashLender { uint256 amount, bytes calldata data ) external returns (bool); - } +} diff --git a/contracts/interfaces/IERC725.sol b/contracts/interfaces/IERC725.sol index 2309b7fb94a..0111d527c3b 100644 --- a/contracts/interfaces/IERC725.sol +++ b/contracts/interfaces/IERC725.sol @@ -7,6 +7,13 @@ interface IERC725 { event ContractCreated(address indexed contractAddress); function getData(bytes32 key) external view returns (bytes32 value); + function setData(bytes32 key, bytes32 value) external; - function execute(uint256 operationType, address to, uint256 value, bytes calldata _data) external; + + function execute( + uint256 operationType, + address to, + uint256 value, + bytes calldata _data + ) external; } From e80c369df6e22d09aa55d4a50e96673ce7a894e2 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 15:42:37 +0200 Subject: [PATCH 14/23] fix inheritance order --- contracts/interfaces/IERC1363.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/interfaces/IERC1363.sol b/contracts/interfaces/IERC1363.sol index fca37847a65..7fafc8fe0d5 100644 --- a/contracts/interfaces/IERC1363.sol +++ b/contracts/interfaces/IERC1363.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import "./IERC20.sol"; import "./IERC165.sol"; -interface IERC1363 is IERC20, IERC165 { +interface IERC1363 is IERC165, IERC20 { /* * Note: the ERC-165 identifier for this interface is 0x4bbee2df. * 0x4bbee2df === From 0cf0ba1e8ccd3b3a9f66667003892a809919e0a7 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 16:14:35 +0200 Subject: [PATCH 15/23] update readme --- contracts/interfaces/README.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index 2b238918009..3b2e7e53c50 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -8,7 +8,6 @@ List of standardized interfaces, usefull to interract with third party contracts {{IERC20}} {{IERC20Metadata}} {{IERC165}} -{{IERC173}} {{IERC721}} {{IERC721Receiver}} {{IERC721Enumerable}} From 28a5329044f620dc5ea6abf8db7300774ddd09c7 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 16:22:04 +0200 Subject: [PATCH 16/23] add IERC2612 alias ro IERC20Draft --- contracts/interfaces/README.adoc | 2 +- contracts/interfaces/draft-IERC2612.sol | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index 3b2e7e53c50..e130cb0a9a5 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -1,4 +1,4 @@ -= Utilities += Interfaces [.readme-notice] NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils diff --git a/contracts/interfaces/draft-IERC2612.sol b/contracts/interfaces/draft-IERC2612.sol index 96bc0bab949..83a80ac93ff 100644 --- a/contracts/interfaces/draft-IERC2612.sol +++ b/contracts/interfaces/draft-IERC2612.sol @@ -3,3 +3,5 @@ pragma solidity ^0.8.0; import "../token/ERC20/extensions/draft-IERC20Permit.sol"; + +interface IERC2612 is IERC20Permit {} From e7c29a142b43f167e155960396a50204dca055fe Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 16:30:00 +0200 Subject: [PATCH 17/23] improved interface docs --- contracts/interfaces/README.adoc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index e130cb0a9a5..3411c1b207f 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -3,8 +3,33 @@ [.readme-notice] NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils -List of standardized interfaces, usefull to interract with third party contracts that implement them. +== List of standardized interfaces +These interfaces are available as `.sol` files, and also as compiler `.json` ABI files (through the npm package). These +are usefull to interract with third party contracts that implement them. +- {IERC20} +- {IERC20Metadata} +- {IERC165} +- {IERC721} +- {IERC721Receiver} +- {IERC721Enumerable} +- {IERC721Metadata} +- {IERC725} +- {IERC777} +- {IERC777Recipient} +- {IERC777Sender} +- {IERC1155} +- {IERC1155Receiver} +- {IERC1155MetadataURI} +- {IERC1271} +- {IERC1363} +- {IERC1820Implementer} +- {IERC1820Registry} +- {IERC2612} +- {IERC3156FlashLender} +- {IERC3156FlashBorrower} + +== Detailed ABI {{IERC20}} {{IERC20Metadata}} {{IERC165}} From b2566ecd6b7114c9cea3f85508b148d3ca518043 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 5 Aug 2021 11:39:50 -0300 Subject: [PATCH 18/23] remove missing interfaces --- contracts/interfaces/README.adoc | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index 3411c1b207f..8309bb543b6 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -30,24 +30,19 @@ are usefull to interract with third party contracts that implement them. - {IERC3156FlashBorrower} == Detailed ABI -{{IERC20}} -{{IERC20Metadata}} -{{IERC165}} -{{IERC721}} -{{IERC721Receiver}} -{{IERC721Enumerable}} -{{IERC721Metadata}} + {{IERC725}} -{{IERC777}} -{{IERC777Recipient}} -{{IERC777Sender}} -{{IERC1155}} -{{IERC1155Receiver}} -{{IERC1155MetadataURI}} + {{IERC1271}} + {{IERC1363}} + +{{IERC1363Receiver}} + {{IERC1820Implementer}} + {{IERC1820Registry}} -{{IERC2612}} + {{IERC3156FlashLender}} + {{IERC3156FlashBorrower}} From 419d1821e3f25c31e9bec605afd8e5c15c83f852 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 5 Aug 2021 11:40:07 -0300 Subject: [PATCH 19/23] fix access control docs --- contracts/access/IAccessControl.sol | 4 ++-- contracts/access/README.adoc | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/contracts/access/IAccessControl.sol b/contracts/access/IAccessControl.sol index 35325967308..46147924361 100644 --- a/contracts/access/IAccessControl.sol +++ b/contracts/access/IAccessControl.sol @@ -20,7 +20,7 @@ interface IAccessControl { * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role - * bearer except when using {_setupRole}. + * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); @@ -42,7 +42,7 @@ interface IAccessControl { * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * - * To change a role's admin, use {_setRoleAdmin}. + * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); diff --git a/contracts/access/README.adoc b/contracts/access/README.adoc index ed8dcc5a5d6..2e84c09ad43 100644 --- a/contracts/access/README.adoc +++ b/contracts/access/README.adoc @@ -12,6 +12,10 @@ This directory provides ways to restrict who can access the functions of a contr {{Ownable}} +{{IAccessControl}} + {{AccessControl}} +{{IAccessControlEnumerable}} + {{AccessControlEnumerable}} From 439ab2c7a1673af0154cb5c2f86614fe509e73bd Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 16:59:34 +0200 Subject: [PATCH 20/23] add IERC2612 detailed ABI --- contracts/interfaces/README.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index 8309bb543b6..80365306972 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -43,6 +43,8 @@ are usefull to interract with third party contracts that implement them. {{IERC1820Registry}} +{{IERC2612}} + {{IERC3156FlashLender}} {{IERC3156FlashBorrower}} From 8f794c8c79dbfa49330d9117dcf11edc3e3eb21b Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 18:30:15 +0200 Subject: [PATCH 21/23] remove ERC725 which is not final --- contracts/interfaces/IERC725.sol | 19 ------------------- contracts/interfaces/README.adoc | 3 --- 2 files changed, 22 deletions(-) delete mode 100644 contracts/interfaces/IERC725.sol diff --git a/contracts/interfaces/IERC725.sol b/contracts/interfaces/IERC725.sol deleted file mode 100644 index 0111d527c3b..00000000000 --- a/contracts/interfaces/IERC725.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -interface IERC725 { - event DataChanged(bytes32 indexed key, bytes32 indexed value); - event ContractCreated(address indexed contractAddress); - - function getData(bytes32 key) external view returns (bytes32 value); - - function setData(bytes32 key, bytes32 value) external; - - function execute( - uint256 operationType, - address to, - uint256 value, - bytes calldata _data - ) external; -} diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index 80365306972..1f17b1eb82e 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -14,7 +14,6 @@ are usefull to interract with third party contracts that implement them. - {IERC721Receiver} - {IERC721Enumerable} - {IERC721Metadata} -- {IERC725} - {IERC777} - {IERC777Recipient} - {IERC777Sender} @@ -31,8 +30,6 @@ are usefull to interract with third party contracts that implement them. == Detailed ABI -{{IERC725}} - {{IERC1271}} {{IERC1363}} From 9fdf9a45ade023dfe26b23fb06dba1936851e312 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 18:36:47 +0200 Subject: [PATCH 22/23] Add ERC2981, which is final --- contracts/interfaces/IERC2981.sol | 22 ++++++++++++++++++++++ contracts/interfaces/README.adoc | 3 +++ 2 files changed, 25 insertions(+) create mode 100644 contracts/interfaces/IERC2981.sol diff --git a/contracts/interfaces/IERC2981.sol b/contracts/interfaces/IERC2981.sol new file mode 100644 index 00000000000..c49221844bc --- /dev/null +++ b/contracts/interfaces/IERC2981.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC165.sol"; + +/** + * @dev Interface for the NFT Royalty Standard + */ +interface IERC2981 is IERC165 { + /** + * @notice Called with the sale price to determine how much royalty is owed and to whom. + * @param _tokenId - the NFT asset queried for royalty information + * @param _salePrice - the sale price of the NFT asset specified by _tokenId + * @return receiver - address of who should be sent the royalty payment + * @return royaltyAmount - the royalty payment amount for _salePrice + */ + function royaltyInfo(uint256 tokenId, uint256 salePrice) + external + view + returns (address receiver, uint256 royaltyAmount); +} diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc index 1f17b1eb82e..943b43235f3 100644 --- a/contracts/interfaces/README.adoc +++ b/contracts/interfaces/README.adoc @@ -25,6 +25,7 @@ are usefull to interract with third party contracts that implement them. - {IERC1820Implementer} - {IERC1820Registry} - {IERC2612} +- {IERC2981} - {IERC3156FlashLender} - {IERC3156FlashBorrower} @@ -42,6 +43,8 @@ are usefull to interract with third party contracts that implement them. {{IERC2612}} +{{IERC2981}} + {{IERC3156FlashLender}} {{IERC3156FlashBorrower}} From 1728f0ed2d49dbceea3396899ba99371d16492a7 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 5 Aug 2021 18:39:23 +0200 Subject: [PATCH 23/23] fix natspec --- contracts/interfaces/IERC2981.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/interfaces/IERC2981.sol b/contracts/interfaces/IERC2981.sol index c49221844bc..0ea8844552f 100644 --- a/contracts/interfaces/IERC2981.sol +++ b/contracts/interfaces/IERC2981.sol @@ -10,10 +10,10 @@ import "./IERC165.sol"; interface IERC2981 is IERC165 { /** * @notice Called with the sale price to determine how much royalty is owed and to whom. - * @param _tokenId - the NFT asset queried for royalty information - * @param _salePrice - the sale price of the NFT asset specified by _tokenId + * @param tokenId - the NFT asset queried for royalty information + * @param salePrice - the sale price of the NFT asset specified by `tokenId` * @return receiver - address of who should be sent the royalty payment - * @return royaltyAmount - the royalty payment amount for _salePrice + * @return royaltyAmount - the royalty payment amount for `salePrice` */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external