From 1b8c234c776ebb70c5c7b28d37ea17dcf118b542 Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Tue, 28 Nov 2023 13:19:52 +0000 Subject: [PATCH 1/9] Add support interface --- crosschain-resolver/contracts/IExtendedResolver.sol | 8 ++++++++ crosschain-resolver/contracts/ITargetResolver.sol | 12 ++++++++++++ crosschain-resolver/contracts/L1Resolver.sol | 11 ++++++++++- crosschain-resolver/test/testResolver.ts | 5 +++++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 crosschain-resolver/contracts/IExtendedResolver.sol create mode 100644 crosschain-resolver/contracts/ITargetResolver.sol diff --git a/crosschain-resolver/contracts/IExtendedResolver.sol b/crosschain-resolver/contracts/IExtendedResolver.sol new file mode 100644 index 00000000..63a44392 --- /dev/null +++ b/crosschain-resolver/contracts/IExtendedResolver.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +interface IExtendedResolver{ + function resolve( + bytes calldata name, bytes calldata data + ) external view returns (bytes memory result); +} diff --git a/crosschain-resolver/contracts/ITargetResolver.sol b/crosschain-resolver/contracts/ITargetResolver.sol new file mode 100644 index 00000000..3268a640 --- /dev/null +++ b/crosschain-resolver/contracts/ITargetResolver.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +interface ITargetResolver{ + function setTarget( + bytes32 node, address target + ) external; + + function getTarget( + bytes memory name,uint256 offset + ) external view returns (bytes32 node, address target); +} diff --git a/crosschain-resolver/contracts/L1Resolver.sol b/crosschain-resolver/contracts/L1Resolver.sol index d9cb25c3..918c4ba9 100644 --- a/crosschain-resolver/contracts/L1Resolver.sol +++ b/crosschain-resolver/contracts/L1Resolver.sol @@ -11,7 +11,8 @@ import {IAddrResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profi import {IAddressResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IAddressResolver.sol"; import {ITextResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol"; import {IContentHashResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IContentHashResolver.sol"; - +import {IExtendedResolver} from './IExtendedResolver.sol'; +import {ITargetResolver} from './ITargetResolver.sol'; contract L1Resolver is EVMFetchTarget { using EVMFetcher for EVMFetcher.EVMFetchRequest; @@ -210,4 +211,12 @@ contract L1Resolver is EVMFetchTarget { ) public pure returns (bytes memory) { return abi.encode(values[1]); } + + function supportsInterface( + bytes4 interfaceId + ) public pure returns (bool) { + return + interfaceId == type(IExtendedResolver).interfaceId || + interfaceId == type(ITargetResolver).interfaceId; + } } diff --git a/crosschain-resolver/test/testResolver.ts b/crosschain-resolver/test/testResolver.ts index d3f7d443..0c5cde52 100644 --- a/crosschain-resolver/test/testResolver.ts +++ b/crosschain-resolver/test/testResolver.ts @@ -290,4 +290,9 @@ describe('Crosschain Resolver', () => { const decoded = i.decodeFunctionResult("contenthash", result2) expect(decoded[0]).to.equal(contenthash); }) + + it("should support wildcard interfaceid", async() => { + expect(await target.supportsInterface('0x6c4787ef')).to.equal(true) // ITargetResolver + expect(await target.supportsInterface('0x9061b923')).to.equal(true) // IExtendedResolver + }) }); \ No newline at end of file From 3bb8cc39cab8edce99ea03996f858d0233b8d1e3 Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:42:10 +0000 Subject: [PATCH 2/9] Use ens-contracts IExtendedResolver --- crosschain-resolver/contracts/IExtendedResolver.sol | 8 -------- crosschain-resolver/contracts/L1Resolver.sol | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 crosschain-resolver/contracts/IExtendedResolver.sol diff --git a/crosschain-resolver/contracts/IExtendedResolver.sol b/crosschain-resolver/contracts/IExtendedResolver.sol deleted file mode 100644 index 63a44392..00000000 --- a/crosschain-resolver/contracts/IExtendedResolver.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -interface IExtendedResolver{ - function resolve( - bytes calldata name, bytes calldata data - ) external view returns (bytes memory result); -} diff --git a/crosschain-resolver/contracts/L1Resolver.sol b/crosschain-resolver/contracts/L1Resolver.sol index 918c4ba9..4d8ca85f 100644 --- a/crosschain-resolver/contracts/L1Resolver.sol +++ b/crosschain-resolver/contracts/L1Resolver.sol @@ -11,7 +11,7 @@ import {IAddrResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profi import {IAddressResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IAddressResolver.sol"; import {ITextResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol"; import {IContentHashResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IContentHashResolver.sol"; -import {IExtendedResolver} from './IExtendedResolver.sol'; +import "@ensdomains/ens-contracts/contracts/resolvers/profiles/IExtendedResolver.sol"; import {ITargetResolver} from './ITargetResolver.sol'; contract L1Resolver is EVMFetchTarget { From 4fb19071c3be446a46b8d80058b83a8363ca848d Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:54:14 +0000 Subject: [PATCH 3/9] Add support interface to reverse registrar --- .../contracts/L1ReverseResolver.sol | 10 ++++++++++ .../test/testReverseResolver.ts | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol b/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol index 7f038a30..397f4a31 100644 --- a/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol +++ b/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol @@ -4,6 +4,8 @@ pragma solidity ^0.8.17; import {EVMFetcher} from '@ensdomains/evm-verifier/contracts/EVMFetcher.sol'; import {EVMFetchTarget} from '@ensdomains/evm-verifier/contracts/EVMFetchTarget.sol'; import {IEVMVerifier} from '@ensdomains/evm-verifier/contracts/IEVMVerifier.sol'; +import "@ensdomains/ens-contracts/contracts/resolvers/profiles/INameResolver.sol"; +import "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol"; contract L1ReverseResolver is EVMFetchTarget { using EVMFetcher for EVMFetcher.EVMFetchRequest; @@ -67,4 +69,12 @@ contract L1ReverseResolver is EVMFetchTarget { ) public pure returns (string memory) { return string(values[1]); } + + function supportsInterface( + bytes4 interfaceId + ) public pure returns (bool) { + return + interfaceId == type(ITextResolver).interfaceId || + interfaceId == type(INameResolver).interfaceId; + } } diff --git a/crosschain-reverse-resolver/test/testReverseResolver.ts b/crosschain-reverse-resolver/test/testReverseResolver.ts index 9c362bb3..7f9be73a 100644 --- a/crosschain-reverse-resolver/test/testReverseResolver.ts +++ b/crosschain-reverse-resolver/test/testReverseResolver.ts @@ -114,4 +114,8 @@ describe('Crosschain Reverse Resolver', () => { expect(result2).to.equal(value); }) + it("should support interface", async() => { + expect(await target.supportsInterface('0x59d1d43c')).to.equal(true) // ITextResolver + expect(await target.supportsInterface('0x691f3431')).to.equal(true) // INameResolver + }) }); From 2bd055c3ee60ad379868ec242c45f8dec667b17e Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Tue, 28 Nov 2023 16:00:29 +0000 Subject: [PATCH 4/9] Change test name --- crosschain-resolver/test/testResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crosschain-resolver/test/testResolver.ts b/crosschain-resolver/test/testResolver.ts index 0c5cde52..67dc43fc 100644 --- a/crosschain-resolver/test/testResolver.ts +++ b/crosschain-resolver/test/testResolver.ts @@ -291,7 +291,7 @@ describe('Crosschain Resolver', () => { expect(decoded[0]).to.equal(contenthash); }) - it("should support wildcard interfaceid", async() => { + it("should support interface", async() => { expect(await target.supportsInterface('0x6c4787ef')).to.equal(true) // ITargetResolver expect(await target.supportsInterface('0x9061b923')).to.equal(true) // IExtendedResolver }) From ac19f164913cf17324bbbf9f46c4b10bbafb2580 Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Tue, 28 Nov 2023 17:44:47 +0000 Subject: [PATCH 5/9] Update L1 deployment contract address for base and OP --- crosschain-resolver/README.md | 4 ++-- crosschain-resolver/contracts/L1Resolver.sol | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crosschain-resolver/README.md b/crosschain-resolver/README.md index 39a317da..0d5e3113 100644 --- a/crosschain-resolver/README.md +++ b/crosschain-resolver/README.md @@ -110,7 +110,7 @@ const l2resolverAddress = await l2Factory.predictAddress(ETH_ADDRESS) - DelegatableResolverRegistrar = [DelegatableResolverRegistrar](https://goerli-optimism.etherscan.io/address/0x2b07cf3ef421a5ff1cb6f437036bdef132eea37b#writeContract) = Demo contract that allow anyone to register subname under `op.evmgateway.eth` on [L2 resolver on `op.evmgateway.eth`](https://goerli-optimism.etherscan.io/address/0x96753bd0D9bdd98d3a84837B5933078AF49aF12d#writeContract) #### L1 -- L1Resolver = [0x65a0963A2941A13a96FcDCfE36c94c6a341f26E5](https://goerli.etherscan.io/address/0x65a0963A2941A13a96FcDCfE36c94c6a341f26E5) = Currently `op.evmgateway.eth` is set to the resolver +- L1Resolver = [0x7Bf57B0a683CC964B0fEe30633A72F5c05464a0f](https://goerli.etherscan.io/address/0x7Bf57B0a683CC964B0fEe30633A72F5c05464a0f) = Currently `op.evmgateway.eth` is set to the resolver ### Base @@ -121,7 +121,7 @@ const l2resolverAddress = await l2Factory.predictAddress(ETH_ADDRESS) - DelegatableResolverRegistrar = [DelegatableResolverRegistrar](https://goerli.basescan.org/address/0xe0356133c3c43cbb623543488e607e4e349eaa10#code) = Demo contract that allow anyone to register subname under `base.evmgateway.eth` on [L2 resolver on `base.evmgateway.eth`](https://goerli.basescan.org/address/0xE4B18eFbF71d516046514598FD7FcFbad4beC742) #### L1 -- L1Resolver = [0x052D7E10D55Ae12b4F62cdE18dBb7E938efa230D](https://goerli.etherscan.io/address/0x052D7E10D55Ae12b4F62cdE18dBb7E938efa230D) = Currently `base.evmgateway.eth` is set to the resolver +- L1Resolver = [0x3Ac25843A1F696fe2166C5dE127FD4f2832F4d42](https://goerli.etherscan.io/address/0x3Ac25843A1F696fe2166C5dE127FD4f2832F4d42) = Currently `base.evmgateway.eth` is set to the resolver ## Usage diff --git a/crosschain-resolver/contracts/L1Resolver.sol b/crosschain-resolver/contracts/L1Resolver.sol index 4d8ca85f..6b7a54b7 100644 --- a/crosschain-resolver/contracts/L1Resolver.sol +++ b/crosschain-resolver/contracts/L1Resolver.sol @@ -17,9 +17,9 @@ import {ITargetResolver} from './ITargetResolver.sol'; contract L1Resolver is EVMFetchTarget { using EVMFetcher for EVMFetcher.EVMFetchRequest; using BytesUtils for bytes; - IEVMVerifier immutable verifier; - ENS immutable ens; - INameWrapper immutable nameWrapper; + IEVMVerifier public immutable verifier; + ENS public immutable ens; + INameWrapper public immutable nameWrapper; mapping(bytes32 => address) targets; uint256 constant COIN_TYPE_ETH = 60; uint256 constant RECORD_VERSIONS_SLOT = 0; From 7fb012844a7418b0d37f00860f05ec8e8faf5cb1 Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:51:27 +0000 Subject: [PATCH 6/9] Remove offset from getTarget --- crosschain-resolver/README.md | 2 +- crosschain-resolver/contracts/ITargetResolver.sol | 6 +----- crosschain-resolver/contracts/L1Resolver.sol | 13 +++++++++---- crosschain-resolver/scripts/getaddr.ts | 4 ++-- crosschain-resolver/test/testResolver.ts | 10 +++++----- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/crosschain-resolver/README.md b/crosschain-resolver/README.md index 0d5e3113..0d3bdcbb 100644 --- a/crosschain-resolver/README.md +++ b/crosschain-resolver/README.md @@ -214,7 +214,7 @@ Once done, set addrss of the subname from the operator, wait 10~20 min, then que Go to [Base L1 resolver](https://goerli.etherscan.io/address/0x052D7E10D55Ae12b4F62cdE18dBb7E938efa230D#readContract) ``` -[node, target] = l1resolver.getTarget(encodedname, 0) +[node, target] = l1resolver.getTarget(encodedname) ``` #### Step 2: Deploy the registrar contract diff --git a/crosschain-resolver/contracts/ITargetResolver.sol b/crosschain-resolver/contracts/ITargetResolver.sol index 3268a640..b7f0b797 100644 --- a/crosschain-resolver/contracts/ITargetResolver.sol +++ b/crosschain-resolver/contracts/ITargetResolver.sol @@ -2,11 +2,7 @@ pragma solidity ^0.8.17; interface ITargetResolver{ - function setTarget( - bytes32 node, address target - ) external; - function getTarget( - bytes memory name,uint256 offset + bytes memory name ) external view returns (bytes32 node, address target); } diff --git a/crosschain-resolver/contracts/L1Resolver.sol b/crosschain-resolver/contracts/L1Resolver.sol index 6b7a54b7..00f95b29 100644 --- a/crosschain-resolver/contracts/L1Resolver.sol +++ b/crosschain-resolver/contracts/L1Resolver.sol @@ -73,19 +73,24 @@ contract L1Resolver is EVMFetchTarget { /** * @dev Returns the L2 target address that can answer queries for `name`. * @param name DNS encoded ENS name to query - * @param offset The offset of the label to query recursively. * @return node The node of the name * @return target The L2 resolver address to verify against. */ function getTarget( + bytes memory name + ) public view returns (bytes32 node, address target) { + return _getTarget(name, 0); + } + + function _getTarget( bytes memory name, uint256 offset - ) public view returns (bytes32 node, address target) { + ) private view returns (bytes32 node, address target) { uint256 len = name.readUint8(offset); node = bytes32(0); if (len > 0) { bytes32 label = name.keccak(offset + 1, len); - (node, target) = getTarget( + (node, target) = _getTarget( name, offset + len + 1 ); @@ -112,7 +117,7 @@ contract L1Resolver is EVMFetchTarget { * @return result result of the call */ function resolve(bytes calldata name, bytes calldata data) external view returns (bytes memory result) { - (, address target) = getTarget(name, 0); + (, address target) = _getTarget(name, 0); bytes4 selector = bytes4(data); if (selector == IAddrResolver.addr.selector) { diff --git a/crosschain-resolver/scripts/getaddr.ts b/crosschain-resolver/scripts/getaddr.ts index a018ba65..fd0008d6 100644 --- a/crosschain-resolver/scripts/getaddr.ts +++ b/crosschain-resolver/scripts/getaddr.ts @@ -1,7 +1,7 @@ import packet from 'dns-packet'; const encodeName = (name) => '0x' + packet.name.encode(name).toString('hex') const l1abi = [ - "function getTarget(bytes,uint256) view returns (bytes32, address)", + "function getTarget(bytes) view returns (bytes32, address)", "function addr(bytes32) view returns (address)", "function resolve(bytes,bytes) view returns (bytes)", ] @@ -32,7 +32,7 @@ export const main = async () => { } console.log({ENS_NAME, resolver, encodedname, node}) const l1resolver = new ethers.Contract(resolver.address, l1abi, l1provider); - const target = await l1resolver.getTarget(encodedname, 0) + const target = await l1resolver.getTarget(encodedname) const l2resolverAddress = target[1] console.log('Target is set to ' + l2resolverAddress); const l2resolver = new ethers.Contract(l2resolverAddress, l2abi, l2provider); diff --git a/crosschain-resolver/test/testResolver.ts b/crosschain-resolver/test/testResolver.ts index 67dc43fc..ff811351 100644 --- a/crosschain-resolver/test/testResolver.ts +++ b/crosschain-resolver/test/testResolver.ts @@ -159,13 +159,13 @@ describe('Crosschain Resolver', () => { }catch(e){ } - const result = await target.getTarget(incorrectname, 0) + const result = await target.getTarget(incorrectname) expect(result[1]).to.equal(EMPTY_ADDRESS); }) it("should allow owner to set target", async() => { await target.setTarget(node, signerAddress) - const result = await target.getTarget(encodeName(name), 0) + const result = await target.getTarget(encodeName(name)) expect(result[1]).to.equal(signerAddress); }) @@ -174,7 +174,7 @@ describe('Crosschain Resolver', () => { const encodedsubname = encodeName(subname) const subnode = ethers.namehash(subname) await target.setTarget(node, signerAddress) - const result = await target.getTarget(encodedsubname, 0) + const result = await target.getTarget(encodedsubname) expect(result[0]).to.equal(subnode); expect(result[1]).to.equal(signerAddress); }) @@ -193,7 +193,7 @@ describe('Crosschain Resolver', () => { const wrappedtnode = ethers.namehash(`${label}.eth`) await target.setTarget(wrappedtnode, resolverAddress) const encodedname = encodeName(`${label}.eth`) - const result = await target.getTarget(encodedname, 0) + const result = await target.getTarget(encodedname) expect(result[1]).to.equal(resolverAddress); }) @@ -292,7 +292,7 @@ describe('Crosschain Resolver', () => { }) it("should support interface", async() => { - expect(await target.supportsInterface('0x6c4787ef')).to.equal(true) // ITargetResolver + expect(await target.supportsInterface('0x15f64386')).to.equal(true) // ITargetResolver expect(await target.supportsInterface('0x9061b923')).to.equal(true) // IExtendedResolver }) }); \ No newline at end of file From f7fe6cda4dbc9b8a84afff0ae46713dc0c16991e Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:53:20 +0000 Subject: [PATCH 7/9] Inherit Interfaces --- crosschain-resolver/contracts/L1Resolver.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crosschain-resolver/contracts/L1Resolver.sol b/crosschain-resolver/contracts/L1Resolver.sol index 00f95b29..824d2bc8 100644 --- a/crosschain-resolver/contracts/L1Resolver.sol +++ b/crosschain-resolver/contracts/L1Resolver.sol @@ -14,7 +14,7 @@ import {IContentHashResolver} from "@ensdomains/ens-contracts/contracts/resolver import "@ensdomains/ens-contracts/contracts/resolvers/profiles/IExtendedResolver.sol"; import {ITargetResolver} from './ITargetResolver.sol'; -contract L1Resolver is EVMFetchTarget { +contract L1Resolver is EVMFetchTarget, ITargetResolver, IExtendedResolver { using EVMFetcher for EVMFetcher.EVMFetchRequest; using BytesUtils for bytes; IEVMVerifier public immutable verifier; From 25065345ca724758e95f0fd08d04d1626e65bbe3 Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:57:48 +0000 Subject: [PATCH 8/9] Inherit interfaces for ReverseResolver --- crosschain-reverse-resolver/contracts/L1ReverseResolver.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol b/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol index 397f4a31..eaabac5f 100644 --- a/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol +++ b/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol @@ -7,7 +7,7 @@ import {IEVMVerifier} from '@ensdomains/evm-verifier/contracts/IEVMVerifier.sol' import "@ensdomains/ens-contracts/contracts/resolvers/profiles/INameResolver.sol"; import "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol"; -contract L1ReverseResolver is EVMFetchTarget { +contract L1ReverseResolver is EVMFetchTarget, INameResolver, ITextResolver { using EVMFetcher for EVMFetcher.EVMFetchRequest; IEVMVerifier immutable verifier; address immutable target; From 428fd9fb83cd4e4078226c7109f907d58e432f15 Mon Sep 17 00:00:00 2001 From: Makoto Inoue <2630+makoto@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:50:34 +0000 Subject: [PATCH 9/9] Add ERC165 signature --- crosschain-resolver/contracts/L1Resolver.sol | 8 +++++--- crosschain-resolver/test/testResolver.ts | 1 + .../contracts/L1ReverseResolver.sol | 8 +++++--- crosschain-reverse-resolver/test/testReverseResolver.ts | 1 + 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/crosschain-resolver/contracts/L1Resolver.sol b/crosschain-resolver/contracts/L1Resolver.sol index 824d2bc8..4a1ba3bb 100644 --- a/crosschain-resolver/contracts/L1Resolver.sol +++ b/crosschain-resolver/contracts/L1Resolver.sol @@ -13,8 +13,9 @@ import {ITextResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profi import {IContentHashResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IContentHashResolver.sol"; import "@ensdomains/ens-contracts/contracts/resolvers/profiles/IExtendedResolver.sol"; import {ITargetResolver} from './ITargetResolver.sol'; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -contract L1Resolver is EVMFetchTarget, ITargetResolver, IExtendedResolver { +contract L1Resolver is EVMFetchTarget, ITargetResolver, IExtendedResolver, ERC165 { using EVMFetcher for EVMFetcher.EVMFetchRequest; using BytesUtils for bytes; IEVMVerifier public immutable verifier; @@ -219,9 +220,10 @@ contract L1Resolver is EVMFetchTarget, ITargetResolver, IExtendedResolver { function supportsInterface( bytes4 interfaceId - ) public pure returns (bool) { + ) public override view returns (bool) { return interfaceId == type(IExtendedResolver).interfaceId || - interfaceId == type(ITargetResolver).interfaceId; + interfaceId == type(ITargetResolver).interfaceId || + super.supportsInterface(interfaceId); } } diff --git a/crosschain-resolver/test/testResolver.ts b/crosschain-resolver/test/testResolver.ts index ff811351..ece5e399 100644 --- a/crosschain-resolver/test/testResolver.ts +++ b/crosschain-resolver/test/testResolver.ts @@ -294,5 +294,6 @@ describe('Crosschain Resolver', () => { it("should support interface", async() => { expect(await target.supportsInterface('0x15f64386')).to.equal(true) // ITargetResolver expect(await target.supportsInterface('0x9061b923')).to.equal(true) // IExtendedResolver + expect(await target.supportsInterface('0x01ffc9a7')).to.equal(true) // ERC-165 support }) }); \ No newline at end of file diff --git a/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol b/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol index eaabac5f..c5cdf910 100644 --- a/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol +++ b/crosschain-reverse-resolver/contracts/L1ReverseResolver.sol @@ -6,8 +6,9 @@ import {EVMFetchTarget} from '@ensdomains/evm-verifier/contracts/EVMFetchTarget. import {IEVMVerifier} from '@ensdomains/evm-verifier/contracts/IEVMVerifier.sol'; import "@ensdomains/ens-contracts/contracts/resolvers/profiles/INameResolver.sol"; import "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -contract L1ReverseResolver is EVMFetchTarget, INameResolver, ITextResolver { +contract L1ReverseResolver is EVMFetchTarget, INameResolver, ITextResolver, ERC165 { using EVMFetcher for EVMFetcher.EVMFetchRequest; IEVMVerifier immutable verifier; address immutable target; @@ -72,9 +73,10 @@ contract L1ReverseResolver is EVMFetchTarget, INameResolver, ITextResolver { function supportsInterface( bytes4 interfaceId - ) public pure returns (bool) { + ) public override view returns (bool) { return interfaceId == type(ITextResolver).interfaceId || - interfaceId == type(INameResolver).interfaceId; + interfaceId == type(INameResolver).interfaceId || + super.supportsInterface(interfaceId); } } diff --git a/crosschain-reverse-resolver/test/testReverseResolver.ts b/crosschain-reverse-resolver/test/testReverseResolver.ts index 7f9be73a..146f13c9 100644 --- a/crosschain-reverse-resolver/test/testReverseResolver.ts +++ b/crosschain-reverse-resolver/test/testReverseResolver.ts @@ -117,5 +117,6 @@ describe('Crosschain Reverse Resolver', () => { it("should support interface", async() => { expect(await target.supportsInterface('0x59d1d43c')).to.equal(true) // ITextResolver expect(await target.supportsInterface('0x691f3431')).to.equal(true) // INameResolver + expect(await target.supportsInterface('0x01ffc9a7')).to.equal(true) // ERC-165 support }) });