diff --git a/contracts/reverseRegistrar/IL2ReverseResolver.sol b/contracts/reverseRegistrar/IL2ReverseResolver.sol index 391581c5..1df761a1 100644 --- a/contracts/reverseRegistrar/IL2ReverseResolver.sol +++ b/contracts/reverseRegistrar/IL2ReverseResolver.sol @@ -1,20 +1,41 @@ // SPDX-License-Identifier: MIT - pragma solidity ^0.8.4; +/// @notice Interface for the L2 reverse resolver interface IL2ReverseResolver { + /// @notice Thrown when the specified address is not the owner of the contract + error NotOwnerOfContract(); + + /// @notice Sets the `name()` record for the reverse ENS record associated with + /// the calling account. + /// @param name The name to set + /// @return The ENS node hash of the reverse record function setName(string memory name) external returns (bytes32); + /// @notice Sets the `name()` record for the reverse ENS record associated with + /// the addr provided account. + /// Can be used if the addr is a contract that is owned by an SCA. + /// @param addr The address to set the name for + /// @param name The name to set + /// @return The ENS node hash of the reverse record function setNameForAddr( address addr, string memory name ) external returns (bytes32); + /// @notice Sets the `name()` record for the reverse ENS record associated with + /// the contract provided that is owned with `Ownable`. + /// @param contractAddr The address of the contract to set the name for + /// @param owner The owner of the contract (via Ownable) + /// @param name The name to set + /// @param signatureExpiry The expiry of the signature + /// @param signature The signature of an address that will return true on isValidSignature for the owner + /// @return The ENS node hash of the reverse record function setNameForAddrWithSignatureAndOwnable( address contractAddr, address owner, - string memory name, - uint256 inceptionDate, - bytes memory signature + string calldata name, + uint256 signatureExpiry, + bytes calldata signature ) external returns (bytes32); } diff --git a/contracts/reverseRegistrar/IReverseRegistrar.sol b/contracts/reverseRegistrar/IReverseRegistrar.sol index 2b63c0c1..99d1927c 100644 --- a/contracts/reverseRegistrar/IReverseRegistrar.sol +++ b/contracts/reverseRegistrar/IReverseRegistrar.sol @@ -1,18 +1,53 @@ // SPDX-License-Identifier: MIT - pragma solidity ^0.8.4; +/// @notice Interface for the reverse registrar interface IReverseRegistrar { + /// @notice Emitted when a reverse record is claimed. + /// @param addr The address that the reverse record is claimed for + /// @param node The ENS node hash of the reverse record + event ReverseClaimed(address indexed addr, bytes32 indexed node); + + /// @notice Emitted when the default resolver is changed. + /// @param resolver The resolver that was set + event DefaultResolverChanged(address indexed resolver); + + /// @notice Thrown when the caller is not authorised to perform the action + error Unauthorised(); + + /// @notice Thrown when the resolver address is zero + error ResolverAddressZero(); + + /// @notice Sets the default resolver + /// @param resolver The resolver to set function setDefaultResolver(address resolver) external; + /// @notice Transfers ownership of the reverse ENS record associated with the + /// calling account. + /// @param owner The address to set as the owner of the reverse record in ENS. + /// @return The ENS node hash of the reverse record function claim(address owner) external returns (bytes32); + /// @notice Transfers ownership of the reverse ENS record associated with the + /// addr provided account. + /// @param addr The address to claim the reverse record for + /// @param owner The address to set as the owner of the reverse record + /// @param resolver The resolver of the reverse node + /// @return The ENS node hash of the reverse record function claimForAddr( address addr, address owner, address resolver ) external returns (bytes32); + /// @notice Transfers ownership of the reverse ENS record associated with the + /// addr provided account using a signature to authorise. + /// @param addr The address to claim the reverse record for + /// @param owner The address to set as the owner of the reverse record + /// @param resolver The resolver of the reverse node + /// @param signatureExpiry The expiry of the signature + /// @param signature The signature to authorise the claim + /// @return The ENS node hash of the reverse record function claimForAddrWithSignature( address addr, address owner, @@ -21,13 +56,31 @@ interface IReverseRegistrar { bytes calldata signature ) external returns (bytes32); + /// @notice Transfers ownership of the reverse ENS record associated with the + /// calling account. + /// @param owner The address to set as the owner of the reverse record + /// @param resolver The resolver of the reverse node + /// @return The ENS node hash of the reverse record function claimWithResolver( address owner, address resolver ) external returns (bytes32); + /// @notice Sets the `name()` record for the reverse ENS record associated + /// with the calling account, and updates the resolver to the + /// default reverse resolver. + /// @param name The name to set for the calling account + /// @return The ENS node hash of the reverse record function setName(string memory name) external returns (bytes32); + /// @notice Sets the `name()` record for the reverse ENS record associated + /// with the addr provided account, and updates the resolver to the + /// resolver provided. + /// @param addr The reverse record to set + /// @param owner The owner of the reverse node + /// @param resolver The resolver of the reverse node + /// @param name The name to set for the provided address + /// @return The ENS node hash of the reverse record function setNameForAddr( address addr, address owner, @@ -35,6 +88,16 @@ interface IReverseRegistrar { string memory name ) external returns (bytes32); + /// @notice Sets the `name()` record for the reverse ENS record associated + /// with the addr provided account using a signature to authorise, + /// and updates the resolver to the resolver provided. + /// @param addr The reverse record to set + /// @param owner The owner of the reverse node + /// @param resolver The resolver of the reverse node + /// @param signatureExpiry The expiry of the signature + /// @param signature The signature to authorise the claim + /// @param name The name to set for the provided address + /// @return The ENS node hash of the reverse record function setNameForAddrWithSignature( address addr, address owner, @@ -44,5 +107,9 @@ interface IReverseRegistrar { string memory name ) external returns (bytes32); + /// @notice Returns the ENS node hash for the reverse record associated with + /// the addr provided account. + /// @param addr The address to get the reverse node hash for + /// @return The ENS node hash function node(address addr) external pure returns (bytes32); } diff --git a/contracts/reverseRegistrar/ISignatureReverseResolver.sol b/contracts/reverseRegistrar/ISignatureReverseResolver.sol index 3d8024d5..1c2897c6 100644 --- a/contracts/reverseRegistrar/ISignatureReverseResolver.sol +++ b/contracts/reverseRegistrar/ISignatureReverseResolver.sol @@ -1,17 +1,37 @@ // SPDX-License-Identifier: MIT - pragma solidity ^0.8.4; +/// @notice Interface for the signature reverse resolver interface ISignatureReverseResolver { - event ReverseClaimed(address indexed addr, bytes32 indexed node); - event NameChanged(bytes32 indexed node, string name); + /// @notice Emitted when the name of a reverse record is changed. + /// @param addr The address of the reverse record + /// @param node The ENS node hash of the reverse record + /// @param name The name of the reverse record + event NameChanged(address indexed addr, bytes32 indexed node, string name); + /// @notice Sets the `name()` record for the reverse ENS record associated with + /// the addr provided account using a signature. + /// @param addr The address to set the name for + /// @param name The name of the reverse record + /// @param signatureExpiry Date when the signature expires + /// @param signature The signature from the addr + /// @return The ENS node hash of the reverse record function setNameForAddrWithSignature( address addr, - string memory name, - uint256 inceptionDate, - bytes memory signature + string calldata name, + uint256 signatureExpiry, + bytes calldata signature ) external returns (bytes32); + /// @notice Returns the name associated with an ENS node hash, for reverse resolution. + /// Defined in ENSIP-3. + /// @param node The ENS node hash to query. + /// @return The associated name. function name(bytes32 node) external view returns (string memory); + + /// @notice Returns the ENS node hash for the reverse record associated with + /// the addr provided account. + /// @param addr The address to get the reverse node hash for + /// @return The ENS node hash + function node(address addr) external view returns (bytes32); } diff --git a/contracts/reverseRegistrar/L2ReverseResolver.sol b/contracts/reverseRegistrar/L2ReverseResolver.sol index 33f398a2..3584b89a 100644 --- a/contracts/reverseRegistrar/L2ReverseResolver.sol +++ b/contracts/reverseRegistrar/L2ReverseResolver.sol @@ -6,19 +6,13 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import {ENS} from "../registry/ENS.sol"; -import {INameResolver} from "../resolvers/profiles/INameResolver.sol"; import {Multicallable} from "../resolvers/Multicallable.sol"; - import {IL2ReverseResolver} from "./IL2ReverseResolver.sol"; -import {SignatureReverseResolver, Unauthorised} from "./SignatureReverseResolver.sol"; +import {SignatureReverseResolver} from "./SignatureReverseResolver.sol"; import {SignatureUtils} from "./SignatureUtils.sol"; -error NotOwnerOfContract(); - -/** - * A L2 reverse resolver. Deployed to each L2 chain. - */ +/// @title L2 Reverse Resolver +/// @notice An L2 reverse resolver. Deployed to each L2 chain. contract L2ReverseResolver is ERC165, Multicallable, @@ -28,13 +22,13 @@ contract L2ReverseResolver is using SignatureUtils for bytes; using ECDSA for bytes32; + /// @notice The addr namespace. Equal to the namehash of + /// `${coinTypeHex}.reverse`. bytes32 public immutable L2ReverseNode; - /* - * @dev Constructor - * @param _L2ReverseNode The namespace to set. The converntion is '${coinType}.reverse' - * @param _coinType The cointype converted from the chainId of the chain this contract is deployed to. - */ + /// @notice Sets the namespace and coin type + /// @param _L2ReverseNode The namespace to set. The converntion is '${coinType}.reverse' + /// @param _coinType The cointype converted from the chainId of the chain this contract is deployed to. constructor( bytes32 _L2ReverseNode, uint256 _coinType @@ -42,21 +36,14 @@ contract L2ReverseResolver is L2ReverseNode = _L2ReverseNode; } + /// @dev Checks if the caller is authorised function isAuthorised(address addr) internal view override { if (addr != msg.sender && !ownsContract(addr, msg.sender)) { revert Unauthorised(); } } - /** - * @dev Sets the name for a contract that is owned by a SCW using a signature - * @param contractAddr The reverse node to set - * @param owner The owner of the contract (via Ownable) - * @param name The name of the reverse record - * @param signatureExpiry Date when the signature expires - * @param signature The signature of an address that will return true on isValidSignature for the owner - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IL2ReverseResolver function setNameForAddrWithSignatureAndOwnable( address contractAddr, address owner, @@ -87,46 +74,33 @@ contract L2ReverseResolver is signature.validateSignatureWithExpiry(owner, message, signatureExpiry); - _setName(node, name); - emit ReverseClaimed(contractAddr, node); - + _setName(contractAddr, node, name); return node; } - /** - * @dev Sets the `name()` record for the reverse ENS record associated with - * the calling account. - * @param name The name to set for this address. - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IL2ReverseResolver function setName(string calldata name) public override returns (bytes32) { return setNameForAddr(msg.sender, name); } - /** - * @dev Sets the `name()` record for the reverse ENS record associated with - * the addr provided account. - * Can be used if the addr is a contract that is owned by a SCW. - * @param name The name to set for this address. - * @return The ENS node hash of the reverse record. - */ - + /// @inheritdoc IL2ReverseResolver function setNameForAddr( address addr, string calldata name ) public authorised(addr) returns (bytes32) { bytes32 node = _getNamehash(addr); - _setName(node, name); - emit ReverseClaimed(addr, node); - + _setName(addr, node, name); return node; } + /// @dev Checks if the provided contractAddr is a contract and is owned by the + /// provided addr. function ownsContract( address contractAddr, address addr ) internal view returns (bool) { + if (contractAddr.code.length == 0) return false; try Ownable(contractAddr).owner() returns (address owner) { return owner == addr; } catch { @@ -134,6 +108,7 @@ contract L2ReverseResolver is } } + /// @inheritdoc ERC165 function supportsInterface( bytes4 interfaceID ) diff --git a/contracts/reverseRegistrar/L2ReverseResolverWithMigration.sol b/contracts/reverseRegistrar/L2ReverseResolverWithMigration.sol index d05e5c71..d6ff53b7 100644 --- a/contracts/reverseRegistrar/L2ReverseResolverWithMigration.sol +++ b/contracts/reverseRegistrar/L2ReverseResolverWithMigration.sol @@ -6,9 +6,15 @@ import {L2ReverseResolver} from "./L2ReverseResolver.sol"; import {INameResolver} from "../resolvers/profiles/INameResolver.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +/// @notice An L2 reverse resolver tha allows migrating from a prior resolver. contract L2ReverseResolverWithMigration is L2ReverseResolver, Ownable { + /// @notice The old reverse resolver INameResolver immutable oldReverseResolver; + /// @notice Sets the namespace, coin type, and old reverse resolver + /// @param _L2ReverseNode The namespace to set. The converntion is '${coinType}.reverse' + /// @param _coinType The cointype converted from the chainId of the chain this contract is deployed to. + /// @param _oldReverseResolver The old reverse resolver constructor( bytes32 _L2ReverseNode, uint256 _coinType, @@ -17,12 +23,14 @@ contract L2ReverseResolverWithMigration is L2ReverseResolver, Ownable { oldReverseResolver = _oldReverseResolver; } + /// @notice Migrates the names from the old reverse resolver to the new one. + /// Only callable by the owner. + /// @param addresses The addresses to migrate function batchSetName(address[] calldata addresses) external onlyOwner { for (uint256 i = 0; i < addresses.length; i++) { bytes32 node = _getNamehash(addresses[i]); string memory name = oldReverseResolver.name(node); - _setName(node, name); - emit ReverseClaimed(addresses[i], node); + _setName(addresses[i], node, name); } } } diff --git a/contracts/reverseRegistrar/ReverseRegistrar.sol b/contracts/reverseRegistrar/ReverseRegistrar.sol index 27a9b524..9c1532c6 100644 --- a/contracts/reverseRegistrar/ReverseRegistrar.sol +++ b/contracts/reverseRegistrar/ReverseRegistrar.sol @@ -13,31 +13,29 @@ import {AddressUtils} from "../utils/AddressUtils.sol"; import {IReverseRegistrar} from "./IReverseRegistrar.sol"; import {SignatureUtils} from "./SignatureUtils.sol"; -abstract contract NameResolver { - function setName(bytes32 node, string memory name) public virtual; +interface INameSetterResolver { + function setName(bytes32 node, string memory name) external; } -bytes32 constant lookup = 0x3031323334353637383961626364656600000000000000000000000000000000; - -bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2; - -// namehash('addr.reverse') - +/// @title ENS Reverse Registrar +/// @notice The registrar for reverse records on ENS contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { using SignatureUtils for bytes; using ECDSA for bytes32; using AddressUtils for address; + /// @dev `namehash('addr.reverse')` + bytes32 constant ADDR_REVERSE_NODE = + 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2; + + /// @notice The ENS registry ENS public immutable ens; - NameResolver public defaultResolver; - event ReverseClaimed(address indexed addr, bytes32 indexed node); - event DefaultResolverChanged(NameResolver indexed resolver); + /// @notice The default resolver + INameSetterResolver public defaultResolver; - /** - * @dev Constructor - * @param ensAddr The address of the ENS registry. - */ + /// @notice Sets the ENS registry and claims `addr.reverse` + /// @param ensAddr The address of the ENS registry constructor(ENS ensAddr) { ens = ensAddr; @@ -50,44 +48,33 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { } } + /// @notice Modifier to check if the caller is authorised to perform an action. + /// @param addr The address to check modifier authorised(address addr) { - require( - addr == msg.sender || - controllers[msg.sender] || - ens.isApprovedForAll(addr, msg.sender) || - ownsContract(addr), - "ReverseRegistrar: Caller is not a controller or authorised by address or the address itself" - ); + if ( + addr != msg.sender && + !controllers[msg.sender] && + !ens.isApprovedForAll(addr, msg.sender) && + !ownsContract(addr) + ) { + revert Unauthorised(); + } _; } + /// @inheritdoc IReverseRegistrar function setDefaultResolver(address resolver) public override onlyOwner { - require( - address(resolver) != address(0), - "ReverseRegistrar: Resolver address must not be 0" - ); - defaultResolver = NameResolver(resolver); - emit DefaultResolverChanged(NameResolver(resolver)); + if (address(resolver) == address(0)) revert ResolverAddressZero(); + defaultResolver = INameSetterResolver(resolver); + emit DefaultResolverChanged(resolver); } - /** - * @dev Transfers ownership of the reverse ENS record associated with the - * calling account. - * @param owner The address to set as the owner of the reverse record in ENS. - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function claim(address owner) public override returns (bytes32) { return claimForAddr(msg.sender, owner, address(defaultResolver)); } - /** - * @dev Transfers ownership of the reverse ENS record associated with the - * calling account. - * @param addr The reverse record to set - * @param owner The address to set as the owner of the reverse record in ENS. - * @param resolver The resolver of the reverse node - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function claimForAddr( address addr, address owner, @@ -102,14 +89,7 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { return reverseNode; } - /** - * @dev Transfers ownership of the reverse ENS record associated with the - * calling account. - * @param addr The reverse record to set - * @param owner The address to set as the owner of the reverse record in ENS. - * @param resolver The resolver of the reverse node - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function claimForAddrWithSignature( address addr, address owner, @@ -141,13 +121,7 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { return reverseNode; } - /** - * @dev Transfers ownership of the reverse ENS record associated with the - * calling account. - * @param owner The address to set as the owner of the reverse record in ENS. - * @param resolver The address of the resolver to set; 0 to leave unchanged. - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function claimWithResolver( address owner, address resolver @@ -155,13 +129,7 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { return claimForAddr(msg.sender, owner, resolver); } - /** - * @dev Sets the `name()` record for the reverse ENS record associated with - * the calling account. First updates the resolver to the default reverse - * resolver if necessary. - * @param name The name to set for this address. - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function setName(string calldata name) public override returns (bytes32) { return setNameForAddr( @@ -172,16 +140,7 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { ); } - /** - * @dev Sets the `name()` record for the reverse ENS record associated with - * the account provided. Updates the resolver to a designated resolver - * Only callable by controllers and authorised users - * @param addr The reverse record to set - * @param owner The owner of the reverse node - * @param resolver The resolver of the reverse node - * @param name The name to set for this address. - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function setNameForAddr( address addr, address owner, @@ -189,20 +148,11 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { string calldata name ) public override returns (bytes32) { bytes32 node = claimForAddr(addr, owner, resolver); - NameResolver(resolver).setName(node, name); + INameSetterResolver(resolver).setName(node, name); return node; } - /** - * @dev Sets the `name()` record for the reverse ENS record associated with - * the account provided. Updates the resolver to a designated resolver - * Only callable by controllers and authorised users - * @param addr The reverse record to set - * @param owner The owner of the reverse node - * @param resolver The resolver of the reverse node - * @param name The name to set for this address. - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc IReverseRegistrar function setNameForAddrWithSignature( address addr, address owner, @@ -218,15 +168,11 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { signatureExpiry, signature ); - NameResolver(resolver).setName(node, name); + INameSetterResolver(resolver).setName(node, name); return node; } - /** - * @dev Returns the node hash for a given account's reverse records. - * @param addr The address to hash - * @return The ENS node hash. - */ + /// @inheritdoc IReverseRegistrar function node(address addr) public pure override returns (bytes32) { return keccak256( @@ -234,14 +180,18 @@ contract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar { ); } + /// @dev Checks if the provided address is a contract and is owned by the + /// caller. function ownsContract(address addr) internal view returns (bool) { + if (addr.code.length == 0) return false; try Ownable(addr).owner() returns (address owner) { return owner == msg.sender; - } catch { + } catch (bytes memory /* lowLevelData */) { return false; } } + /// @inheritdoc ERC165 function supportsInterface( bytes4 interfaceID ) public view override(ERC165) returns (bool) { diff --git a/contracts/reverseRegistrar/SignatureReverseResolver.sol b/contracts/reverseRegistrar/SignatureReverseResolver.sol index b61e0fe8..c8b57613 100644 --- a/contracts/reverseRegistrar/SignatureReverseResolver.sol +++ b/contracts/reverseRegistrar/SignatureReverseResolver.sol @@ -11,8 +11,7 @@ import {AddressUtils} from "../utils/AddressUtils.sol"; import {ISignatureReverseResolver} from "./ISignatureReverseResolver.sol"; import {SignatureUtils} from "./SignatureUtils.sol"; -error Unauthorised(); - +/// @notice A reverse resolver that allows setting names with signatures contract SignatureReverseResolver is ISignatureReverseResolver, ERC165 { using SignatureUtils for bytes; using ECDSA for bytes32; @@ -23,31 +22,27 @@ contract SignatureReverseResolver is ISignatureReverseResolver, ERC165 { bytes32 public immutable parentNode; uint256 public immutable coinType; - /* - * @dev Constructor - * @param parentNode The namespace to set. - * @param _coinType The coinType converted from the chainId of the chain this contract is deployed to. - */ + /// @notice The caller is not authorised to perform the action + error Unauthorised(); + + /// @notice Sets the namespace and coin type + /// @param _parentNode The namespace to set + /// @param _coinType The coin type converted from the chain ID of the chain this contract is deployed to constructor(bytes32 _parentNode, uint256 _coinType) { parentNode = _parentNode; coinType = _coinType; } + /// @dev Checks if the caller is authorised modifier authorised(address addr) { isAuthorised(addr); _; } + /// @dev Checks if the caller is authorised function isAuthorised(address addr) internal view virtual {} - /** - * @dev Sets the name for an addr using a signature that can be verified with ERC1271. - * @param addr The reverse record to set - * @param name The name of the reverse record - * @param signatureExpiry Date when the signature expires - * @param signature The resolver of the reverse node - * @return The ENS node hash of the reverse record. - */ + /// @inheritdoc ISignatureReverseResolver function setNameForAddrWithSignature( address addr, string calldata name, @@ -70,39 +65,36 @@ contract SignatureReverseResolver is ISignatureReverseResolver, ERC165 { signature.validateSignatureWithExpiry(addr, message, signatureExpiry); - _setName(node, name); - emit ReverseClaimed(addr, node); + _setName(addr, node, name); return node; } - function _setName(bytes32 node, string memory newName) internal virtual { + /// @dev Sets the name for an address + function _setName( + address addr, + bytes32 node, + string memory newName + ) internal virtual { names[node] = newName; - emit NameChanged(node, newName); + emit NameChanged(addr, node, newName); } - /** - * Returns the name associated with an ENS node, for reverse records. - * Defined in EIP181. - * @param node The ENS node to query. - * @return The associated name. - */ + /// @inheritdoc ISignatureReverseResolver function name(bytes32 node) public view returns (string memory) { return names[node]; } - /** - * @dev Returns the node hash for a given account's reverse records. - * @param addr The address to hash - * @return The ENS node hash. - */ + /// @inheritdoc ISignatureReverseResolver function node(address addr) public view returns (bytes32) { return _getNamehash(addr); } + /// @dev Gets the namehash for an address function _getNamehash(address addr) internal view returns (bytes32) { return keccak256(abi.encodePacked(parentNode, addr.sha3HexAddress())); } + /// @inheritdoc ERC165 function supportsInterface( bytes4 interfaceID ) public view virtual override returns (bool) { diff --git a/contracts/reverseRegistrar/SignatureUtils.sol b/contracts/reverseRegistrar/SignatureUtils.sol index a4b6dc70..e2357db6 100644 --- a/contracts/reverseRegistrar/SignatureUtils.sol +++ b/contracts/reverseRegistrar/SignatureUtils.sol @@ -4,11 +4,20 @@ pragma solidity ^0.8.4; import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; -error InvalidSignature(); -error SignatureExpiryTooHigh(); -error SignatureExpired(); - +/// @notice Utility functions for validating signatures with expiry library SignatureUtils { + /// @notice The signature is invalid + error InvalidSignature(); + /// @notice The signature expiry is too high + error SignatureExpiryTooHigh(); + /// @notice The signature has expired + error SignatureExpired(); + + /// @notice Validates a signature with expiry + /// @param signature The signature to validate + /// @param addr The address that signed the message + /// @param message The message that was signed + /// @param signatureExpiry The expiry of the signature function validateSignatureWithExpiry( bytes memory signature, address addr, diff --git a/test/reverseRegistrar/TestL2ReverseResolver.ts b/test/reverseRegistrar/TestL2ReverseResolver.ts index 288dfd57..dfee3a53 100644 --- a/test/reverseRegistrar/TestL2ReverseResolver.ts +++ b/test/reverseRegistrar/TestL2ReverseResolver.ts @@ -110,15 +110,15 @@ describe('L2ReverseResolver', () => { await expect(l2ReverseResolver.read.name([node])).resolves.toBe(name) }) - it('event ReverseClaimed is emitted', async () => { + it('event NameChanged is emitted', async () => { const { l2ReverseResolver, name, node, accounts } = await loadFixture( setNameFixture, ) await expect(l2ReverseResolver) .write('setName', [name]) - .toEmitEvent('ReverseClaimed') - .withArgs(getAddress(accounts[0].address), node) + .toEmitEvent('NameChanged') + .withArgs(getAddress(accounts[0].address), node, name) }) }) @@ -183,7 +183,7 @@ describe('L2ReverseResolver', () => { await expect(l2ReverseResolver.read.name([node])).resolves.toBe(name) }) - it('event ReverseClaimed is emitted', async () => { + it('event NameChanged is emitted', async () => { const { l2ReverseResolver, name, @@ -199,8 +199,8 @@ describe('L2ReverseResolver', () => { [accounts[0].address, name, signatureExpiry, signature], { account: accounts[1] }, ) - .toEmitEvent('ReverseClaimed') - .withArgs(getAddress(accounts[0].address), node) + .toEmitEvent('NameChanged') + .withArgs(getAddress(accounts[0].address), node, name) }) it('reverts if signature parameters do not match', async () => { @@ -389,7 +389,7 @@ describe('L2ReverseResolver', () => { await expect(l2ReverseResolver.read.name([node])).resolves.toBe(name) }) - it('event ReverseClaimed is emitted', async () => { + it('event NameChanged is emitted', async () => { const { l2ReverseResolver, name, @@ -413,8 +413,8 @@ describe('L2ReverseResolver', () => { ], { account: accounts[1] }, ) - .toEmitEvent('ReverseClaimed') - .withArgs(getAddress(mockOwnable.address), node) + .toEmitEvent('NameChanged') + .withArgs(getAddress(mockOwnable.address), node, name) }) }) }) diff --git a/test/reverseRegistrar/TestReverseRegistrar.ts b/test/reverseRegistrar/TestReverseRegistrar.ts index 7611f0be..5319bd0f 100644 --- a/test/reverseRegistrar/TestReverseRegistrar.ts +++ b/test/reverseRegistrar/TestReverseRegistrar.ts @@ -167,7 +167,7 @@ describe('ReverseRegistrar', () => { accounts[0].address, publicResolver.address, ]) - .toBeRevertedWithoutReason() + .toBeRevertedWithCustomError('Unauthorised') }) it('allows an authorised account to claim a different address', async () => { @@ -304,7 +304,7 @@ describe('ReverseRegistrar', () => { publicResolver.address, 'testname', ]) - .toBeRevertedWithoutReason() + .toBeRevertedWithCustomError('Unauthorised') }) it('allows name to be set for an address if the sender is the address', async () => {