diff --git a/CHANGELOG.md b/CHANGELOG.md index 0430d8736d4..30b1da17338 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * `TransparentUpgradeableProxy`: Removed `admin` and `implementation` getters, which were only callable by the proxy owner and thus not very useful. ([#3820](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3820)) * `ProxyAdmin`: Removed `getProxyAdmin` and `getProxyImplementation` getters. ([#3820](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3820)) * `ERC20`: Deleted `_beforeTokenTransfer` and `_afterTokenTransfer` hooks, added a new internal `_update` function for customizations, and refactored all extensions using those hooks to use `_update` instead. ([#3838](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3838)) + * `ERC165Storage`: Removed this contract in favor of inheritance based approach. ([#3880](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3880)) ### How to upgrade from 4.x @@ -33,6 +34,16 @@ For example, a contract using `ERC20`'s `_beforeTokenTransfer` hook would have t } ``` +#### ERC165Storage + +Users that were registering EIP-165 interfaces with `_registerInterface` from `ERC165Storage` should instead do so so by overriding the `supportsInterface` function as seen below: + +```solidity +function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); +} +``` + ## Unreleased * `ReentrancyGuard`: Add a `_reentrancyGuardEntered` function to expose the guard status. ([#3714](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3714)) diff --git a/contracts/mocks/ERC165StorageMock.sol b/contracts/mocks/ERC165StorageMock.sol deleted file mode 100644 index 4b0bae90865..00000000000 --- a/contracts/mocks/ERC165StorageMock.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165Storage.sol"; - -contract ERC165StorageMock is ERC165Storage { - function registerInterface(bytes4 interfaceId) public { - _registerInterface(interfaceId); - } -} diff --git a/contracts/utils/README.adoc b/contracts/utils/README.adoc index 7fef825a6fd..babaef522ee 100644 --- a/contracts/utils/README.adoc +++ b/contracts/utils/README.adoc @@ -70,8 +70,6 @@ Note that, in all cases, accounts simply _declare_ their interfaces, but they ar {{ERC165}} -{{ERC165Storage}} - {{ERC165Checker}} {{IERC1820Registry}} diff --git a/contracts/utils/introspection/ERC165.sol b/contracts/utils/introspection/ERC165.sol index 3bf5613a6cc..49395f8a1d1 100644 --- a/contracts/utils/introspection/ERC165.sol +++ b/contracts/utils/introspection/ERC165.sol @@ -16,8 +16,6 @@ import "./IERC165.sol"; * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` - * - * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** diff --git a/contracts/utils/introspection/ERC165Storage.sol b/contracts/utils/introspection/ERC165Storage.sol deleted file mode 100644 index c99d9f3fbad..00000000000 --- a/contracts/utils/introspection/ERC165Storage.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol) - -pragma solidity ^0.8.0; - -import "./ERC165.sol"; - -/** - * @dev Storage based implementation of the {IERC165} interface. - * - * Contracts may inherit from this and call {_registerInterface} to declare - * their support of an interface. - */ -abstract contract ERC165Storage is ERC165 { - /** - * @dev Mapping of interface ids to whether or not it's supported. - */ - mapping(bytes4 => bool) private _supportedInterfaces; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId]; - } - - /** - * @dev Registers the contract as an implementer of the interface defined by - * `interfaceId`. Support of the actual ERC165 interface is automatic and - * registering its interface id is not required. - * - * See {IERC165-supportsInterface}. - * - * Requirements: - * - * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). - */ - function _registerInterface(bytes4 interfaceId) internal virtual { - require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); - _supportedInterfaces[interfaceId] = true; - } -} diff --git a/test/utils/introspection/ERC165Storage.test.js b/test/utils/introspection/ERC165Storage.test.js deleted file mode 100644 index 568d64576fe..00000000000 --- a/test/utils/introspection/ERC165Storage.test.js +++ /dev/null @@ -1,25 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); - -const ERC165Mock = artifacts.require('ERC165StorageMock'); - -contract('ERC165Storage', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165Mock.new(); - }); - - it('register interface', async function () { - expect(await this.mock.supportsInterface('0x00000001')).to.be.equal(false); - await this.mock.registerInterface('0x00000001'); - expect(await this.mock.supportsInterface('0x00000001')).to.be.equal(true); - }); - - it('does not allow 0xffffffff', async function () { - await expectRevert(this.mock.registerInterface('0xffffffff'), 'ERC165: invalid interface id'); - }); - - shouldSupportInterfaces([ - 'ERC165', - ]); -});