-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor ERC165 to use function overriding instead of storage (#2505)
Co-authored-by: Francisco Giordano <[email protected]>
- Loading branch information
Showing
12 changed files
with
116 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import "../introspection/ERC165Storage.sol"; | ||
|
||
contract ERC165StorageMock is ERC165Storage { | ||
function registerInterface(bytes4 interfaceId) public { | ||
_registerInterface(interfaceId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
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', | ||
]); | ||
}); |