Fix ERC4906 compliance of ERC721URIStorage (#4055)
Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
@ -15,6 +15,13 @@ abstract contract ERC721URIStorage is IERC4906, ERC721 {
|
|||||||
// Optional mapping for token URIs
|
// Optional mapping for token URIs
|
||||||
mapping(uint256 => string) private _tokenURIs;
|
mapping(uint256 => string) private _tokenURIs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev See {IERC165-supportsInterface}
|
||||||
|
*/
|
||||||
|
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
|
||||||
|
return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev See {IERC721Metadata-tokenURI}.
|
* @dev See {IERC721Metadata-tokenURI}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
|
const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
|
||||||
|
|
||||||
const { expect } = require('chai');
|
const { expect } = require('chai');
|
||||||
|
|
||||||
|
const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior');
|
||||||
|
|
||||||
const ERC721URIStorageMock = artifacts.require('$ERC721URIStorageMock');
|
const ERC721URIStorageMock = artifacts.require('$ERC721URIStorageMock');
|
||||||
|
|
||||||
contract('ERC721URIStorage', function (accounts) {
|
contract('ERC721URIStorage', function (accounts) {
|
||||||
@ -17,6 +18,8 @@ contract('ERC721URIStorage', function (accounts) {
|
|||||||
this.token = await ERC721URIStorageMock.new(name, symbol);
|
this.token = await ERC721URIStorageMock.new(name, symbol);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
shouldSupportInterfaces(['0x49064906']);
|
||||||
|
|
||||||
describe('token URI', function () {
|
describe('token URI', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
await this.token.$_mint(owner, firstTokenId);
|
await this.token.$_mint(owner, firstTokenId);
|
||||||
|
|||||||
@ -100,20 +100,22 @@ function shouldSupportInterfaces(interfaces = []) {
|
|||||||
|
|
||||||
it('supportsInterface uses less than 30k gas', async function () {
|
it('supportsInterface uses less than 30k gas', async function () {
|
||||||
for (const k of interfaces) {
|
for (const k of interfaces) {
|
||||||
const interfaceId = INTERFACE_IDS[k];
|
const interfaceId = INTERFACE_IDS[k] ?? k;
|
||||||
expect(await this.contractUnderTest.supportsInterface.estimateGas(interfaceId)).to.be.lte(30000);
|
expect(await this.contractUnderTest.supportsInterface.estimateGas(interfaceId)).to.be.lte(30000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('all interfaces are reported as supported', async function () {
|
it('all interfaces are reported as supported', async function () {
|
||||||
for (const k of interfaces) {
|
for (const k of interfaces) {
|
||||||
const interfaceId = INTERFACE_IDS[k];
|
const interfaceId = INTERFACE_IDS[k] ?? k;
|
||||||
expect(await this.contractUnderTest.supportsInterface(interfaceId)).to.equal(true);
|
expect(await this.contractUnderTest.supportsInterface(interfaceId)).to.equal(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('all interface functions are in ABI', async function () {
|
it('all interface functions are in ABI', async function () {
|
||||||
for (const k of interfaces) {
|
for (const k of interfaces) {
|
||||||
|
// skip interfaces for which we don't have a function list
|
||||||
|
if (INTERFACES[k] === undefined) continue;
|
||||||
for (const fnName of INTERFACES[k]) {
|
for (const fnName of INTERFACES[k]) {
|
||||||
const fnSig = FN_SIGNATURES[fnName];
|
const fnSig = FN_SIGNATURES[fnName];
|
||||||
expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSig).length).to.equal(1);
|
expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSig).length).to.equal(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user