From 8438b275ffbb855dd18e1e48e16a8f444ec43780 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Thu, 23 Jan 2025 18:21:44 -0300 Subject: [PATCH] refactor: contracts compliant with new version of the ENSIP --- README.md | 12 +-- packages/client/test/db.e2e.spec.ts | 4 +- packages/contracts/src/DatabaseResolver.sol | 22 ++-- packages/contracts/src/L1Resolver.sol | 26 ++--- .../src/interfaces/IWriteDeferral.sol | 101 ------------------ .../src/interfaces/OperationRouter.sol | 64 +++++++++++ packages/contracts/test/L1Resolver.t.sol | 56 +++++----- 7 files changed, 124 insertions(+), 161 deletions(-) delete mode 100644 packages/contracts/src/interfaces/IWriteDeferral.sol create mode 100644 packages/contracts/src/interfaces/OperationRouter.sol diff --git a/README.md b/README.md index 457cc60..daacdbe 100644 --- a/README.md +++ b/README.md @@ -29,15 +29,15 @@ This project not only makes ENS more efficient and cost-effective but also opens | Contract | Network | Address | | --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | -| DatabaseResolver | Ethereum | [0xc1D4903Eba794035d2D81D210325b57a95C8a007](https://sepolia.etherscan.io/address/0xc1D4903Eba794035d2D81D210325b57a95C8a007) | +| DatabaseResolver | Ethereum | [0x464e965E2BA20430d9E35c815c8F73a76D5ea4F6](https://sepolia.etherscan.io/address/0x464e965E2BA20430d9E35c815c8F73a76D5ea4F6) | | ArbitrumVerifier | Ethereum | [0x8fc4a214705e3c40032e99f867d964c012bf8efb](https://sepolia.etherscan.io/address/0x8fc4a214705e3c40032e99f867d964c012bf8efb) | -| L1Resolver | Ethereum | [0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8](https://sepolia.etherscan.io/address/0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8) | +| L1Resolver | Ethereum | [0xa0038AD12102c9Fbe7163D5b1bb286E6F678b4df](https://sepolia.etherscan.io/address/0xa0038AD12102c9Fbe7163D5b1bb286E6F678b4df) | | ENSRegistry | Arbitrum | [0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50](https://sepolia.arbiscan.io/address/0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50) | | ReverseRegistrar | Arbitrum | [0xb3c9ff08671bbadddd0436cc46fbfa005c8da0a7](https://sepolia.arbiscan.io/address/0xb3c9ff08671bbadddd0436cc46fbfa005c8da0a7) | | BaseRegistrarImplementation | Arbitrum | [0x2C6a113C513fa0fd404abcCE3aC8a4BE16ccb651](https://sepolia.arbiscan.io/address/0x2C6a113C513fa0fd404abcCE3aC8a4BE16ccb651) | | NameWrapper | Arbitrum | [0xff4f34ac12a84de527cf9e24856fc8d7c42cc379](https://sepolia.arbiscan.io/address/0xff4f34ac12a84de527cf9e24856fc8d7c42cc379) | | ETHRegistrarController | Arbitrum | [0x263c644d8f5d4bdb44cfab020491ec6fc4ca5271](https://sepolia.arbiscan.io/address/0x263c644d8f5d4bdb44cfab020491ec6fc4ca5271) | -| SubdomainController | Arbitrum | [0x41eede073217084a30f6f3bc2c546bda1f08b5ca](https://sepolia.arbiscan.io/address/0x41eede073217084a30f6f3bc2c546bda1f08b5ca) | +| SubdomainController | Arbitrum | [0x2e28f723818ED7B70a3ec10879309aa39CC4b3D6](https://sepolia.arbiscan.io/address/0x2e28f723818ED7B70a3ec10879309aa39CC4b3D6) | | PublicResolver | Arbitrum | [0x0a33f065c9c8f0F5c56BB84b1593631725F0f3af](https://sepolia.arbiscan.io/address/0x0a33f065c9c8f0F5c56BB84b1593631725F0f3af) | ## Components @@ -79,7 +79,7 @@ try { }) } catch (err) { const data = getRevertErrorData(err) - if (data?.errorName === 'StorageHandledByOffChainDatabase') { + if (data?.errorName === 'OperationHandledOffchain') { const [domain, url, message] = data.args as [ DomainData, string, @@ -104,7 +104,7 @@ try { }) } catch (err) { const data = getRevertErrorData(err) - if (data?.errorName === 'StorageHandledByL2') { + if (data?.errorName === 'OperationHandledOnchain') { const [chainId, contractAddress] = data.args as [bigint, `0x${string}`] await handleL2Storage({ @@ -290,7 +290,7 @@ Domain Register: 1. Find the resolver associated with the given domain through the Universal Resolver 2. Call the `register` function on the resolver passing the address of the Layer 2 resolver that will be managing the properties of a given domain 3. Client calls `setOwner` on the L1 Resolver -4. Client receive a `StorageHandledByL2` revert with the arguments required to call the gateway +4. Client receive a `OperationHandledOnchain` revert with the arguments required to call the gateway 5. Client calls the L2 Resolver with the returned arguments ![domain register](https://github.com/blockful-io/external-resolver/assets/29408363/1ef65db2-a979-4e2f-bb9f-7dde0769fae4) diff --git a/packages/client/test/db.e2e.spec.ts b/packages/client/test/db.e2e.spec.ts index 49915eb..e807ac9 100644 --- a/packages/client/test/db.e2e.spec.ts +++ b/packages/client/test/db.e2e.spec.ts @@ -90,7 +90,7 @@ async function offchainWriting({ args: [ encodedName, encodeFunctionData({ - functionName: 'getDeferralHandler', + functionName: 'getOperationHandler', abi: abiDBResolver, args: [encodeFunctionData(calldata)], }), @@ -105,7 +105,7 @@ async function offchainWriting({ abi: abiDBResolver, data: params as Hex, }) - if (errorResult?.errorName === 'StorageHandledByOffChainDatabase') { + if (errorResult?.errorName === 'OperationHandledOffchain') { const [domain, url, message] = errorResult?.args as [ DomainData, string, diff --git a/packages/contracts/src/DatabaseResolver.sol b/packages/contracts/src/DatabaseResolver.sol index 4e3557d..21909c4 100644 --- a/packages/contracts/src/DatabaseResolver.sol +++ b/packages/contracts/src/DatabaseResolver.sol @@ -20,7 +20,7 @@ import {IMulticallable} from "@ens-contracts/resolvers/IMulticallable.sol"; import {ENSIP16} from "./ENSIP16.sol"; import {SignatureVerifier} from "./SignatureVerifier.sol"; -import {IWriteDeferral} from "./interfaces/IWriteDeferral.sol"; +import {OperationRouter} from "./interfaces/OperationRouter.sol"; import {EnumerableSetUpgradeable} from "./utils/EnumerableSetUpgradeable.sol"; /** @@ -31,7 +31,7 @@ contract DatabaseResolver is ERC165, ENSIP16, IExtendedResolver, - IWriteDeferral, + OperationRouter, AddrResolver, ABIResolver, PubkeyResolver, @@ -112,9 +112,9 @@ contract DatabaseResolver is * @notice Read call for fetching the required parameters for the offchain call * @notice avoiding multiple transactions * @param data The encoded data to be written - * @dev This function reverts with StorageHandledByL2 error to indicate L2 deferral + * @dev This function reverts with OperationHandledOnchain error to indicate L2 deferral */ - function getDeferralHandler(bytes calldata data) public view override { + function getOperationHandler(bytes calldata data) public view override { _offChainStorage(data); } @@ -143,9 +143,9 @@ contract DatabaseResolver is return bytes(this.name(node)); } - if (bytes4(data[:4]) == this.getDeferralHandler.selector) { + if (bytes4(data[:4]) == this.getOperationHandler.selector) { (bytes memory _data) = abi.decode(data[4:], (bytes)); - this.getDeferralHandler(_data); + this.getOperationHandler(_data); } _offChainLookup(data); @@ -418,18 +418,18 @@ contract DatabaseResolver is //////// ENS WRITE DEFERRAL RESOLVER (EIP-5559) //////// /** - * @notice Builds an StorageHandledByOffChainDatabase error. + * @notice Builds an OperationHandledOffchain error. */ function _offChainStorage(bytes calldata callData) private view { - revert StorageHandledByOffChainDatabase( - IWriteDeferral.domainData({ + revert OperationHandledOffchain( + OperationRouter.DomainData({ name: _WRITE_DEFERRAL_DOMAIN_NAME, version: _WRITE_DEFERRAL_DOMAIN_VERSION, chainId: _CHAIN_ID, verifyingContract: address(this) }), gatewayUrl, - IWriteDeferral.messageData({ + OperationRouter.MessageData({ data: callData, sender: msg.sender, expirationTimestamp: block.timestamp @@ -568,7 +568,7 @@ contract DatabaseResolver is ) returns (bool) { - return interfaceID == type(IWriteDeferral).interfaceId + return interfaceID == type(OperationRouter).interfaceId || interfaceID == type(IExtendedResolver).interfaceId || interfaceID == type(IMulticallable).interfaceId || super.supportsInterface(interfaceID); diff --git a/packages/contracts/src/L1Resolver.sol b/packages/contracts/src/L1Resolver.sol index 2a7a474..f828d99 100644 --- a/packages/contracts/src/L1Resolver.sol +++ b/packages/contracts/src/L1Resolver.sol @@ -22,14 +22,14 @@ import {ENSIP16} from "./ENSIP16.sol"; import {EVMFetcher} from "./evmgateway/EVMFetcher.sol"; import {IEVMVerifier} from "./evmgateway/IEVMVerifier.sol"; import {EVMFetchTarget} from "./evmgateway/EVMFetchTarget.sol"; -import {IWriteDeferral} from "./interfaces/IWriteDeferral.sol"; +import {OperationRouter} from "./interfaces/OperationRouter.sol"; import {OffchainRegister} from "./interfaces/WildcardWriting.sol"; contract L1Resolver is EVMFetchTarget, IExtendedResolver, IERC165, - IWriteDeferral, + OperationRouter, IMulticallable, Ownable, ENSIP16 @@ -37,12 +37,6 @@ contract L1Resolver is using EVMFetcher for EVMFetcher.EVMFetchRequest; - //////// ERRORS //////// - - /// @notice Error thrown when an unsupported function is called - /// @dev Used to indicate when a function call is not implemented or allowed - error FunctionNotSupported(); - //////// CONTRACT VARIABLE STATE //////// // address of each target contract @@ -109,9 +103,9 @@ contract L1Resolver is /** * @notice Validates and processes write parameters for deferred storage mutations * @param data The encoded data to be written - * @dev This function reverts with StorageHandledByL2 error to indicate L2 deferral + * @dev This function reverts with OperationHandledOnchain error to indicate L2 deferral */ - function getDeferralHandler(bytes calldata data) public view override { + function getOperationHandler(bytes calldata data) public view override { bytes4 selector = bytes4(data); if (selector == OffchainRegister.register.selector) { @@ -169,9 +163,9 @@ contract L1Resolver is bytes32 node = abi.decode(data[4:], (bytes32)); return _contenthash(node); } - if (selector == this.getDeferralHandler.selector) { + if (selector == this.getOperationHandler.selector) { (bytes memory _data) = abi.decode(data[4:], (bytes)); - this.getDeferralHandler(_data); + this.getOperationHandler(_data); } } @@ -366,10 +360,10 @@ contract L1Resolver is //////// ENS WRITE DEFERRAL RESOLVER (EIP-5559) //////// /** - * @notice Builds an StorageHandledByL2 error. + * @notice Builds an OperationHandledOnchain error. */ function _offChainStorage(address target) internal view { - revert StorageHandledByL2(chainId, target); + revert OperationHandledOnchain(chainId, target); } //////// ENS ERC-165 //////// @@ -381,7 +375,7 @@ contract L1Resolver is returns (bool) { return interfaceID == type(IExtendedResolver).interfaceId - || interfaceID == type(IWriteDeferral).interfaceId + || interfaceID == type(OperationRouter).interfaceId || interfaceID == type(EVMFetchTarget).interfaceId || interfaceID == type(IERC165).interfaceId || interfaceID == type(ENSIP16).interfaceId @@ -407,9 +401,7 @@ contract L1Resolver is * @param target The L2 contract address */ function setTarget(bytes32 key, address target) public onlyOwner { - address prevAddr = targets[key]; targets[key] = target; - emit L2HandlerContractAddressChanged(chainId, prevAddr, target); } function multicall(bytes[] calldata /* data */ ) diff --git a/packages/contracts/src/interfaces/IWriteDeferral.sol b/packages/contracts/src/interfaces/IWriteDeferral.sol deleted file mode 100644 index 48a3dc1..0000000 --- a/packages/contracts/src/interfaces/IWriteDeferral.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -interface IWriteDeferral { - - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /// @notice Event raised when the default chainId is changed for the corresponding L2 handler. - event L2HandlerDefaultChainIdChanged( - uint256 indexed previousChainId, uint256 indexed newChainId - ); - /// @notice Event raised when the contractAddress is changed for the L2 handler corresponding to chainId. - event L2HandlerContractAddressChanged( - uint256 indexed chainId, - address indexed previousContractAddress, - address indexed newContractAddress - ); - - /// @notice Event raised when the url is changed for the corresponding Off-Chain Database handler. - event OffChainDatabaseHandlerURLChanged( - string indexed previousUrl, string indexed newUrl - ); - - /*////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Struct used to define the domain of the typed data signature, defined in EIP-712. - * @param name The user friendly name of the contract that the signature corresponds to. - * @param version The version of domain object being used. - * @param chainId The ID of the chain that the signature corresponds to (ie Ethereum mainnet: 1, Goerli testnet: 5, ...). - * @param verifyingContract The address of the contract that the signature pertains to. - */ - struct domainData { - string name; - string version; - uint64 chainId; - address verifyingContract; - } - - /** - * @notice Struct used to define the message context used to construct a typed data signature, defined in EIP-712, - * to authorize and define the deferred mutation being performed. - * @param data The original ABI encoded function call - * @param sender The address of the user performing the mutation (msg.sender). - * @param expirationTimestamp The timestamp at which the mutation will expire. - */ - struct messageData { - bytes data; - address sender; - uint256 expirationTimestamp; - } - - /*////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @dev Error to raise when mutations are being deferred to an L2. - * @param chainId Chain ID to perform the deferred mutation to. - * @param contractAddress Contract Address at which the deferred mutation should transact with. - */ - error StorageHandledByL2(uint256 chainId, address contractAddress); - - /** - * @dev Error to raise when mutations are being deferred to an Off-Chain Database. - * @param sender the EIP-712 domain definition of the corresponding contract performing the off-chain database, write - * deferral reversion. - * @param url URL to request to perform the off-chain mutation. - * @param data the EIP-712 message signing data context used to authorize and instruct the mutation deferred to the - * off-chain database handler. - * In order to authorize the deferred mutation to be performed, the user must use the domain definition (sender) and message data - * (data) to construct a type data signature request defined in EIP-712. This signature, message data (data), and domainData (sender) - * are then included in the HTTP POST request, denoted sender, data, and signature. - * - * Example HTTP POST request: - * { - * "sender": , - * "data": , - * "signature": - * } - * - */ - error StorageHandledByOffChainDatabase( - domainData sender, string url, messageData data - ); - - /*////////////////////////////////////////////////////////////// - VIEW FUNCTIONS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice View function that simulates the execution of an encoded function call - * @param encodedFunction The ABI encoded function call to simulate - */ - function getDeferralHandler(bytes calldata encodedFunction) external view; - -} diff --git a/packages/contracts/src/interfaces/OperationRouter.sol b/packages/contracts/src/interfaces/OperationRouter.sol new file mode 100644 index 0000000..bc1d8d8 --- /dev/null +++ b/packages/contracts/src/interfaces/OperationRouter.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +interface OperationRouter { + + /** + * @dev Error to raise when an encoded function that is not supported + * @dev is received on the getOperationHandler function + */ + error FunctionNotSupported(); + + /** + * @dev Error to raise when mutations are being deferred onchain + * that being the layer 1 or a layer 2 + * @param chainId Chain ID to perform the deferred mutation to. + * @param contractAddress Contract Address at which the deferred mutation should transact with. + */ + error OperationHandledOnchain(uint256 chainId, address contractAddress); + + /** + * @notice Struct used to define the domain of the typed data signature, defined in EIP-712. + * @param name The user friendly name of the contract that the signature corresponds to. + * @param version The version of domain object being used. + * @param chainId The ID of the chain that the signature corresponds to + * @param verifyingContract The address of the contract that the signature pertains to. + */ + struct DomainData { + string name; + string version; + uint64 chainId; + address verifyingContract; + } + + /** + * @notice Struct used to define the message context for off-chain storage authorization + * @param data The original ABI encoded function call + * @param sender The address of the user performing the mutation (msg.sender). + * @param expirationTimestamp The timestamp at which the mutation will expire. + */ + struct MessageData { + bytes data; + address sender; + uint256 expirationTimestamp; + } + + /** + * @dev Error to raise when mutations are being deferred to an Offchain entity + * @param sender the EIP-712 domain definition + * @param url URL to request to perform the off-chain mutation + * @param data The original ABI encoded function call along with authorization context + */ + error OperationHandledOffchain( + DomainData sender, string url, MessageData data + ); + + /** + * @notice Determines the appropriate handler for an encoded function call + * @param encodedFunction The ABI encoded function call + */ + function getOperationHandler(bytes calldata encodedFunction) + external + view; + +} diff --git a/packages/contracts/test/L1Resolver.t.sol b/packages/contracts/test/L1Resolver.t.sol index 9ecbab1..17f4b28 100644 --- a/packages/contracts/test/L1Resolver.t.sol +++ b/packages/contracts/test/L1Resolver.t.sol @@ -19,7 +19,7 @@ import {OffchainRegister} from "../src/interfaces/WildcardWriting.sol"; import {IEVMVerifier} from "../src/evmgateway/IEVMVerifier.sol"; import {L1Verifier} from "../src/evmgateway/L1Verifier.sol"; import {L1Resolver} from "../src/L1Resolver.sol"; -import {IWriteDeferral} from "../src/interfaces/IWriteDeferral.sol"; +import {OperationRouter} from "../src/interfaces/OperationRouter.sol"; import {ENSHelper} from "../script/ENSHelper.sol"; import {ENSIP16} from "../src/ENSIP16.sol"; @@ -60,7 +60,7 @@ contract L1ResolverTest is Test, ENSHelper { function test_EmitEventOnSetTarget() public { address target = address(0x123); vm.expectEmit(true, true, true, false); - emit IWriteDeferral.L2HandlerContractAddressChanged( + emit OperationRouter.L2HandlerContractAddressChanged( chainId, TARGET_RESOLVER, target ); l1Resolver.setTarget(l1Resolver.TARGET_RESOLVER(), target); @@ -77,7 +77,7 @@ contract L1ResolverTest is Test, ENSHelper { //////// WRITE PARAMS TESTS //////// - function test_GetDeferralHandlerRegister() public { + function test_getOperationHandlerRegister() public { bytes memory name = "test.eth"; bytes memory data = abi.encodeWithSelector( OffchainRegister.register.selector, @@ -90,15 +90,15 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, + OperationRouter.OperationHandledOnchain.selector, chainId, TARGET_REGISTRAR ) ); - l1Resolver.getDeferralHandler(data); + l1Resolver.getOperationHandler(data); } - function test_GetDeferralHandlerSetAddr() public { + function test_getOperationHandlerSetAddr() public { bytes memory data = abi.encodeWithSelector( bytes4(keccak256("setAddr(bytes32,address)")), bytes32(0), @@ -107,15 +107,15 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, + OperationRouter.OperationHandledOnchain.selector, chainId, TARGET_RESOLVER ) ); - l1Resolver.getDeferralHandler(data); + l1Resolver.getOperationHandler(data); } - function test_GetDeferralHandlerSetAddrWithCoinType() public { + function test_getOperationHandlerSetAddrWithCoinType() public { bytes memory data = abi.encodeWithSelector( bytes4(keccak256("setAddr(bytes32,uint256,bytes)")), bytes32(0), @@ -125,15 +125,15 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, + OperationRouter.OperationHandledOnchain.selector, chainId, TARGET_RESOLVER ) ); - l1Resolver.getDeferralHandler(data); + l1Resolver.getOperationHandler(data); } - function test_GetDeferralHandlerSetText() public { + function test_getOperationHandlerSetText() public { bytes memory data = abi.encodeWithSelector( bytes4(keccak256("setText(bytes32,string,string)")), bytes32(0), @@ -143,15 +143,15 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, + OperationRouter.OperationHandledOnchain.selector, chainId, TARGET_RESOLVER ) ); - l1Resolver.getDeferralHandler(data); + l1Resolver.getOperationHandler(data); } - function test_GetDeferralHandlerSetContenthash() public { + function test_getOperationHandlerSetContenthash() public { bytes memory data = abi.encodeWithSelector( bytes4(keccak256("setContenthash(bytes32,bytes)")), bytes32(0), @@ -160,21 +160,21 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, + OperationRouter.OperationHandledOnchain.selector, chainId, TARGET_RESOLVER ) ); - l1Resolver.getDeferralHandler(data); + l1Resolver.getOperationHandler(data); } - function test_GetDeferralHandlerUnsupportedFunction() public { + function test_getOperationHandlerUnsupportedFunction() public { bytes memory data = abi.encodeWithSelector( bytes4(keccak256("unsupportedFunction()")), bytes32(0) ); vm.expectRevert(L1Resolver.FunctionNotSupported.selector); - l1Resolver.getDeferralHandler(data); + l1Resolver.getOperationHandler(data); } function test_RevertWhen_GetAddr() public { @@ -191,7 +191,9 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, chainId, target + OperationRouter.OperationHandledOnchain.selector, + chainId, + target ) ); l1Resolver.setText(bytes32(0), "com.twitter", "@blockful"); @@ -213,7 +215,9 @@ contract L1ResolverTest is Test, ENSHelper { vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, chainId, target + OperationRouter.OperationHandledOnchain.selector, + chainId, + target ) ); l1Resolver.setContenthash(bytes32(0), bytes("contenthash")); @@ -232,7 +236,9 @@ contract L1ResolverTest is Test, ENSHelper { l1Resolver.setTarget(l1Resolver.TARGET_RESOLVER(), target); vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, chainId, target + OperationRouter.OperationHandledOnchain.selector, + chainId, + target ) ); l1Resolver.setAddr(bytes32(0), address(0x456)); @@ -244,7 +250,9 @@ contract L1ResolverTest is Test, ENSHelper { vm.prank(address(0x2024)); vm.expectRevert( abi.encodeWithSelector( - IWriteDeferral.StorageHandledByL2.selector, chainId, target + OperationRouter.OperationHandledOnchain.selector, + chainId, + target ) ); l1Resolver.setAddr(bytes32(0), address(0x456)); @@ -282,7 +290,7 @@ contract L1ResolverTest is Test, ENSHelper { l1Resolver.supportsInterface(type(IExtendedResolver).interfaceId) ); assertTrue( - l1Resolver.supportsInterface(type(IWriteDeferral).interfaceId) + l1Resolver.supportsInterface(type(OperationRouter).interfaceId) ); assertTrue(l1Resolver.supportsInterface(type(IERC165).interfaceId)); assertTrue(l1Resolver.supportsInterface(type(ENSIP16).interfaceId));