Skip to content

Commit

Permalink
Name Resolver natspec and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stevieraykatz committed Nov 15, 2024
1 parent 8928c15 commit d9ce766
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
30 changes: 19 additions & 11 deletions src/L2/resolver/NameResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,46 @@ import {INameResolver} from "ens-contracts/resolvers/profiles/INameResolver.sol"

import {ResolverBase} from "./ResolverBase.sol";

/// @title Name Resolver
///
/// @notice ENSIP-3 compliant Name resolver. Adaptation of the ENS NameResolver.sol profile contract, with
/// EIP-7201 storage compliance.
/// https://github.com/ensdomains/ens-contracts/blob/staging/contracts/resolvers/profiles/NameResolver.sol
///
/// @author Coinbase (https://github.com/base-org/basenames)
abstract contract NameResolver is INameResolver, ResolverBase {
struct NameResolverStorage {
/// @notice Names by node and version.
mapping(uint64 version => mapping(bytes32 node => string name)) versionable_names;
}

/// @notice EIP-7201 storage location.
// keccak256(abi.encode(uint256(keccak256("name.resolver.storage")) - 1)) & ~bytes32(uint256(0xff));
bytes32 constant NAME_RESOLVER_STORAGE = 0x23d7cb83bcf6186ccf590f4291f50469cd60b0ac3c413e76ea47a810986d8500;

/**
* Sets the name associated with an ENS node, for reverse records.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
*/
/// @notice Sets the name associated with an ENS node.
///
/// @param node The node to update.
function setName(bytes32 node, string calldata newName) external virtual authorised(node) {
_getNameResolver().versionable_names[_getResolverBaseStorage().recordVersions[node]][node] = newName;
emit NameChanged(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.
*/
/// @notice Returns the name associated with an ENS node.
///
/// @param node The ENS node to query.
///
/// @return The associated name.
function name(bytes32 node) external view virtual override returns (string memory) {
return _getNameResolver().versionable_names[_getResolverBaseStorage().recordVersions[node]][node];
}

/// @notice ERC-165 compliance.
function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) {
return interfaceID == type(INameResolver).interfaceId || super.supportsInterface(interfaceID);
}

/// @notice EIP-7201 storage pointer fetch helper.
function _getNameResolver() internal pure returns (NameResolverStorage storage $) {
assembly {
$.slot := NAME_RESOLVER_STORAGE
Expand Down
2 changes: 1 addition & 1 deletion test/UpgradeableL2Resolver/SetInterface.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ contract Counter is ICounter, ERC165 {
function set(uint256 x_) external {
x = x_;
}
/// @notice ERC-165 compliance.

/// @notice ERC-165 compliance.
function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) {
return interfaceID == type(ICounter).interfaceId || super.supportsInterface(interfaceID);
}
Expand Down
21 changes: 21 additions & 0 deletions test/UpgradeableL2Resolver/SetName.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {UpgradeableL2ResolverBase} from "./UpgradeableL2ResolverBase.t.sol";
import {ResolverBase} from "src/L2/resolver/ResolverBase.sol";
import {NameResolver} from "src/L2/resolver/NameResolver.sol";

contract SetName is UpgradeableL2ResolverBase {
function test_reverts_forUnauthorizedUser() public {
vm.expectRevert(abi.encodeWithSelector(ResolverBase.NotAuthorized.selector, node, notUser));
vm.prank(notUser);
resolver.setName(node, name);
}

function test_setsTheName() public {
vm.prank(user);
resolver.setName(node, name);
string memory retName = resolver.name(node);
assertEq(keccak256(bytes(name)), keccak256(bytes(retName)));
}
}

0 comments on commit d9ce766

Please sign in to comment.