Skip to content
This repository was archived by the owner on Nov 7, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions contracts/Dummy.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pragma solidity ^0.5.3;
pragma solidity ^0.8.4;

import "@rsksmart/rns-registry/contracts/RNS.sol";

contract Dummy {
}
contract Dummy {}
34 changes: 17 additions & 17 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
pragma solidity ^0.5.3;
pragma solidity ^0.8.4;

contract Migrations {
address public owner;
uint public lastCompletedMigration;
address public owner;
uint256 public lastCompletedMigration;

constructor() public {
owner = msg.sender;
}
constructor() {
owner = msg.sender;
}

modifier restricted() {
require(msg.sender == owner);
_;
}
modifier restricted() {
require(msg.sender == owner);
_;
}

function setCompleted(uint completed) external restricted {
lastCompletedMigration = completed;
}
function setCompleted(uint256 completed) external restricted {
lastCompletedMigration = completed;
}

function upgrade(address newAddress) external restricted {
Migrations upgraded = Migrations(newAddress);
upgraded.setCompleted(lastCompletedMigration);
}
function upgrade(address newAddress) external restricted {
Migrations upgraded = Migrations(newAddress);
upgraded.setCompleted(lastCompletedMigration);
}
}
30 changes: 20 additions & 10 deletions contracts/NameResolver.sol
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
pragma solidity ^0.5.3;
pragma solidity ^0.8.4;

import "./ReverseResolverBase.sol";
import "@rsksmart/rns-registry/contracts/AbstractRNS.sol";
import {ReverseResolverBase} from "./ReverseResolverBase.sol";
import {AbstractRNS} from "@rsksmart/rns-registry/contracts/AbstractRNS.sol";

/// source: https://github.com/ensdomains/resolvers/blob/master/contracts/profiles/NameResolver.sol
contract NameResolver is ReverseResolverBase {
bytes4 constant private NAME_INTERFACE_ID = 0x691f3431;
bytes4 private constant NAME_INTERFACE_ID = 0x691f3431;
AbstractRNS rns;

event NameChanged(bytes32 indexed node, string name);

mapping(bytes32=>string) names;
mapping(bytes32 => string) names;

modifier onlyOwner (bytes32 node) {
modifier onlyOwner(bytes32 node) {
require(msg.sender == rns.owner(node), "Only owner");
_;
}

constructor (AbstractRNS _rns) public {
constructor(AbstractRNS _rns) {
rns = _rns;
}

/// @notice Sets the name associated with an RNS node, for reverse records.
/// @dev May only be called by the owner of that node in the RNS registry.
/// @param node The node to update.
/// @param newName The name to set.
function setName(bytes32 node, string calldata newName) external onlyOwner(node) {
function setName(bytes32 node, string calldata newName)
external
onlyOwner(node)
{
names[node] = newName;
emit NameChanged(node, newName);
}
Expand All @@ -38,7 +41,14 @@ contract NameResolver is ReverseResolverBase {
return names[node];
}

function supportsInterface(bytes4 interfaceID) public pure returns(bool) {
return interfaceID == NAME_INTERFACE_ID || super.supportsInterface(interfaceID);
function supportsInterface(bytes4 interfaceID)
public
pure
override
returns (bool)
{
return
interfaceID == NAME_INTERFACE_ID ||
super.supportsInterface(interfaceID);
}
}
94 changes: 52 additions & 42 deletions contracts/ReverseRegistrar.sol
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
pragma solidity ^0.5.3;
pragma solidity ^0.8.4;

import "@rsksmart/rns-registry/contracts/AbstractRNS.sol";
import "@openzeppelin/contracts/ownership/Ownable.sol";
import "@openzeppelin/contracts/access/Roles.sol";
import "./NameResolver.sol";
import {AbstractRNS} from "@rsksmart/rns-registry/contracts/AbstractRNS.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {NameResolver} from "./NameResolver.sol";

contract ReverseRegistrar is Ownable {
using Roles for Roles.Role;
contract ReverseRegistrar is AccessControl, Ownable {
bytes32 constant RSK_REGISTRAR_ROLE = keccak256("RSK_REGISTRAR_ROLE");

// namehash('addr.reverse')
bytes32 public constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
bytes32 public constant ADDR_REVERSE_NODE =
0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;

AbstractRNS public rns;

modifier onlyRskRegistrar {
require(isRskRegistrar(msg.sender), "Not rsk registrar.");
// CONSIDER: The use of this modifier could be replaced by onlyRole(RSK_REGISTRAR_ROLE);
modifier onlyRskRegistrar() {
require(hasRole(RSK_REGISTRAR_ROLE, msg.sender), "Not rsk registrar.");
_;
}

/// @dev Constructor
/// @param rnsAddr The address of the RNS registry.
constructor(AbstractRNS rnsAddr) public {
constructor(AbstractRNS rnsAddr) {
rns = rnsAddr;
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}

/// @notice Sets the name record on that name to the specified name
/// @dev Sets the resolver for the name hex(msg.sender).addr.reverse to a default resolver
/// @param name The name to set for this address.
/// @return The RNS node hash of the reverse record.
function setName(string calldata name) external returns (bytes32 _node) {
_node = claim(address(this));
NameResolver(rns.resolver(_node)).setName(_node, name);
/// @return node_ - The RNS node hash of the reverse record.
function setName(string calldata name) external returns (bytes32 node_) {
node_ = claim(address(this));
NameResolver(rns.resolver(node_)).setName(node_, name);
}

/// @notice Transfer ownership of the name hex(msg.sender).addr.reverse
Expand All @@ -48,41 +51,54 @@ contract ReverseRegistrar is Ownable {
/// @dev Transfer ownership of the name to the provided address.
/// @param recordOwner The address to set as the owner of the reverse record in RNS.
/// @param resolver The address of the resolver to set; 0 to leave default.
/// @return The RNS node hash of the reverse record.
function claimWithResolver(address recordOwner, address resolver) external returns (bytes32 _node) {
/// @return node_ - The RNS node hash of the reverse record.
function claimWithResolver(address recordOwner, address resolver)
external
returns (bytes32 node_)
{
bytes32 label = sha3HexAddress(msg.sender);
_node = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label));
node_ = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label));

if (rns.owner(_node) != address(this))
if (rns.owner(node_) != address(this))
rns.setSubnodeOwner(ADDR_REVERSE_NODE, label, address(this));
// registrar owns the node, with default resolver

if (resolver != address(0x0) && resolver != rns.resolver(ADDR_REVERSE_NODE))
rns.setResolver(_node, resolver);
if (
resolver != address(0x0) &&
resolver != rns.resolver(ADDR_REVERSE_NODE)
) rns.setResolver(node_, resolver);
// node has default resolver for 0x00 or resolver value

if (recordOwner != address(this))
rns.setOwner(_node, recordOwner);
if (recordOwner != address(this)) rns.setOwner(node_, recordOwner);
// owner owns node
}

/// @dev Returns the node hash for a given account's reverse records.
/// @param addr The address to hash
/// @return The RNS node hash.
function node(address addr) external pure returns (bytes32) {
return keccak256(abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr)));
return
keccak256(
abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr))
);
}

/// @dev An optimised function to compute the sha3 of the lower-case
/// hexadecimal representation of an Ethereum address.
/// @param addr The address to hash
/// @return The SHA3 hash of the lower-case hexadecimal encoding of the
/// @return ret - The SHA3 hash of the lower-case hexadecimal encoding of the
/// input address.
function sha3HexAddress(address addr) private pure returns (bytes32 ret) {
assembly {
let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000
let
lookup
:= 0x3031323334353637383961626364656600000000000000000000000000000000

for { let i := 40 } gt(i, 0) { } {
for {
let i := 40
} gt(i, 0) {

} {
i := sub(i, 1)
mstore8(i, byte(and(addr, 0xf), lookup))
addr := div(addr, 0x10)
Expand All @@ -106,43 +122,37 @@ contract ReverseRegistrar is Ownable {
/// @notice Allows .rsk registrars to create reverse records.
/// @param addr The addr to register
/// @param label The label to prepend to .rsk and set as name.
function rskClaim(address addr, string calldata label) external onlyRskRegistrar {
function rskClaim(address addr, string calldata label)
external
onlyRskRegistrar
{
bytes32 _label = sha3HexAddress(addr);
rns.setSubnodeOwner(ADDR_REVERSE_NODE, _label, address(this));
bytes32 _node = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, _label));
NameResolver(
rns.resolver(_node)
).setName(
NameResolver(rns.resolver(_node)).setName(
_node,
string(
abi.encodePacked(
bytes(label),
bytes(".rsk")
)
)
string(abi.encodePacked(bytes(label), bytes(".rsk")))
);
}

Roles.Role rskRegistrars;

/// @notice Give an account access to registrar role.
/// @dev Only owner.
/// @param registrar new registrar.
function addRskRegistrar(address registrar) external onlyOwner {
rskRegistrars.add(registrar);
grantRole(RSK_REGISTRAR_ROLE, registrar);
}

/// @notice Check if an account has registrar role.
/// @param registrar to query if has registrar role.
/// @return true if it has registrar role.
function isRskRegistrar(address registrar) public view returns (bool) {
return rskRegistrars.has(registrar);
return hasRole(RSK_REGISTRAR_ROLE, registrar);
}

/// @notice Remove an account's access to registrar role.
/// @dev Only owner
/// @param registrar registrar to remove from registrar role.
function removeRskRegistrar(address registrar) external onlyOwner {
rskRegistrars.remove(registrar);
revokeRole(RSK_REGISTRAR_ROLE, registrar);
}
}
9 changes: 7 additions & 2 deletions contracts/ReverseResolverBase.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
pragma solidity ^0.5.3;
pragma solidity ^0.8.4;

/// source: https://github.com/ensdomains/resolvers/blob/master/contracts/ResolverBase.sol
contract ReverseResolverBase {
bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7;

function supportsInterface(bytes4 interfaceID) public pure returns(bool) {
function supportsInterface(bytes4 interfaceID)
public
pure
virtual
returns (bool)
{
return interfaceID == INTERFACE_META_ID;
}
}
20 changes: 11 additions & 9 deletions contracts/ReverseSetup.sol
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
pragma solidity ^0.5.3;
pragma solidity ^0.8.4;

import "@rsksmart/rns-registry/contracts/AbstractRNS.sol";
import {AbstractRNS} from "@rsksmart/rns-registry/contracts/AbstractRNS.sol";

contract ReverseSetup {
AbstractRNS rns;
address nameResolver;
address reverseRegistrar;
address payable reverseOwner;

bytes32 constant REVERSE = 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34;
bytes32 constant ADDR_REVERSE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
bytes32 constant REVERSE =
0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34;
bytes32 constant ADDR_REVERSE =
0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;

constructor (
constructor(
AbstractRNS _rns,
address _nameResolver,
address _reverseRegistrar,
address payable _reverseOwner
) public {
) {
require(_nameResolver != address(0), "No 0 address");
require(_reverseRegistrar != address(0), "No 0 address");
require(_reverseOwner != address(0), "No 0 address");
Expand All @@ -26,12 +28,12 @@ contract ReverseSetup {
reverseOwner = _reverseOwner;
}

function run() external {
function run() external {
require(rns.owner(REVERSE) == address(this), "Not reverse owner");

// run
rns.setResolver(REVERSE, nameResolver);
rns.setSubnodeOwner(REVERSE, keccak256('addr'), reverseRegistrar);
rns.setSubnodeOwner(REVERSE, keccak256("addr"), reverseRegistrar);
rns.setOwner(REVERSE, reverseOwner);

// assert
Expand All @@ -42,5 +44,5 @@ contract ReverseSetup {

// self destruct
selfdestruct(reverseOwner);
}
}
}
Loading