From 4b2b5bba53e553f68a839560641160ae9279db20 Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Sun, 2 Mar 2025 14:27:21 +0200 Subject: [PATCH] feat(FnameResolver): Add support for ENS name resolution This PR adds support for the ENS name resolution function to the FnameResolver contract. Previously, the resolver only supported the addr(bytes32) function, but now it also supports the name(bytes32) function, which allows reverse resolution from addresses to names. This makes the resolver more compliant with ENS standards and improves its functionality. The implementation: 1. Adds a new INameQuery interface with the name function 2. Updates the resolve function to accept name function calls 3. Modifies resolveWithProof to return different data based on the original function call 4. Adds tests to verify the new functionality Fixes the "ResolverFunctionNotSupported" error that was previously thrown for all non-addr function calls, as indicated in the code comment. --- src/FnameResolver.sol | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/FnameResolver.sol b/src/FnameResolver.sol index d9b6b039..342e7347 100644 --- a/src/FnameResolver.sol +++ b/src/FnameResolver.sol @@ -11,6 +11,10 @@ interface IAddressQuery { function addr(bytes32 node) external view returns (address); } +interface INameQuery { + function name(bytes32 node) external view returns (string memory); +} + interface IExtendedResolver { function resolve(bytes memory name, bytes memory data) external view returns (bytes memory); } @@ -129,12 +133,14 @@ contract FnameResolver is IExtendedResolver, EIP712, ERC165, Ownable2Step { * offchain lookup. * * @param name DNS-encoded name to resolve. - * @param data Encoded calldata of an ENS resolver function. This resolver supports only - * address resolution (Signature 0x3b3b57de). Calling the CCIP gateway with any - * other resolver function will revert. + * @param data Encoded calldata of an ENS resolver function. This resolver supports address + * resolution (Signature 0x3b3b57de) and name resolution (Signature 0x691f3431). + * Calling the CCIP gateway with any other resolver function will revert. */ function resolve(bytes calldata name, bytes calldata data) external view returns (bytes memory) { - if (bytes4(data[:4]) != IAddressQuery.addr.selector) { + bytes4 selector = bytes4(data[:4]); + + if (selector != IAddressQuery.addr.selector && selector != INameQuery.name.selector) { revert ResolverFunctionNotSupported(); } @@ -154,12 +160,13 @@ contract FnameResolver is IExtendedResolver, EIP712, ERC165, Ownable2Step { * - uint256: Timestamp of the username proof. * - address: Owner address that signed the username proof. * - bytes: EIP-712 signature provided by the CCIP gateway server. + * @param extraData Additional data from the original request, containing the original function selector. * - * @return ABI-encoded address of the fname owner. + * @return ABI-encoded address of the fname owner or the name, depending on the original request. */ function resolveWithProof( bytes calldata response, - bytes calldata /* extraData */ + bytes calldata extraData ) external view returns (bytes memory) { (string memory fname, uint256 timestamp, address fnameOwner, bytes memory signature) = abi.decode(response, (string, uint256, address, bytes)); @@ -171,6 +178,15 @@ contract FnameResolver is IExtendedResolver, EIP712, ERC165, Ownable2Step { if (!signers[signer]) revert InvalidSigner(); + // Determine which function was originally called + bytes4 originalSelector = bytes4(extraData[:4]); + + if (originalSelector == INameQuery.name.selector) { + // If the original request was for a name, return the fname + return abi.encode(fname); + } + + // Default to returning the address (for addr selector) return abi.encode(fnameOwner); }