Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
update Root api for register/unregister and registrar integration
Browse files Browse the repository at this point in the history
  • Loading branch information
kibagateaux committed Jan 2, 2022
1 parent 717dbf9 commit ad66cb8
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 31 deletions.
16 changes: 11 additions & 5 deletions packages/hardhat/contracts/Root.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,41 @@ contract Root is
}

function setResolver(address resolver) external onlyOwner {
ens.setResolver(ROOT_NODE, resolver);
ens.setResolver(ROOT_NODE, resolver);
}

function register(uint id, address _owner) external onlyController returns(bool) {
function register(bytes32 label, address _owner) external onlyController returns(bool) {
uint id = generateID(label);
require(address(0) == tldControllers[id], 'Cannot register claimed TLD');
if(_exists(id)) {
// Name was previously owned
_burn(id);
}
_mint(_owner, id);
ens.setSubnodeOwner(ROOT_NODE, bytes32(id), _owner);
ens.setSubnodeOwner(ROOT_NODE, label, _owner);
emit TLDRegistered(id, _owner);
tldControllers[id] = msg.sender;
return true;
}

function unregister(uint id) external onlyController returns(bool) {
function unregister(bytes32 label) external onlyController returns(bool) {
uint id = generateID(label);
require(address(0) != tldControllers[id], 'Cannot unregister a nonexistant TLD');
require(msg.sender == tldControllers[id], 'Controller not allowed for NFTLD');
address _owner = ownerOf(id);
if(_exists(id)) {
_burn(id);
}
ens.setSubnodeOwner(ROOT_NODE, bytes32(id), address(0)); // or address(this)?
ens.setSubnodeOwner(ROOT_NODE, label, address(0));
delete tldControllers[id];
emit TLDUnregistered(id, _owner);
return true;
}

function generateID(bytes32 label) internal pure returns (uint) {
return uint(keccak256(abi.encode(ROOT_NODE, label)));
}

/**
* @dev Reclaim ownership of a name in ENS if you own the NFT.
*/
Expand Down
11 changes: 11 additions & 0 deletions packages/hardhat/contracts/oracles/TrustedXNHNSOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ contract TrustedXNHNSOracle is IXNHNSOracle, Ownable {
NAMESPACE = _namespace;
}


/**
* @dev Optimisitically approves requesters for TLD ownership.
* @param tld string of HNS tld to verify ownership of
*/
function requestTLDUpdate(string calldata tld)
external
override
Expand All @@ -31,6 +36,12 @@ contract TrustedXNHNSOracle is IXNHNSOracle, Ownable {
return node;
}

/**
* @dev Allows oracle owner to update TLD ownership.
Only needed if malicious actor calls requestTLDUpdate on TLD they don't own
* @param node ENS hash of tld to claim
* @param owner_ address to give TLD to
*/
function receiveTLDUpdate(bytes32 node, address owner_)
external override
onlyOwner
Expand Down
64 changes: 40 additions & 24 deletions packages/hardhat/contracts/registrars/HNSRegistrar.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@ contract HNSRegistrar {
using SafeMath for uint256;

ENS public ens;
// IPanvalaMember public hnsFund;
bytes32 constant private ROOT_NODE = bytes32(0);

// oracle that requests and stores tld verification data
IXNHNSOracle public xnhnsOracle;

// namespace that this contract lives in
// formal registry of namespaces tbd in a HIP
string public NAMESPACE;

// add versioning var too?

uint256 public constant snitchDeposit = 0.1 ether;
uint256 public constant minTLDDeposit = 0.1 ether;

// total tld + snitch deposits in contract
uint256 public totalDeposits;

Expand All @@ -42,6 +46,7 @@ contract HNSRegistrar {
event NewOwner(bytes32 indexed node, address owner);
event SnitchedOn(bytes32 indexed node, address indexed owner, address snitch, uint256 snitchReward);
event SnitchesGotStitches(bytes32 indexed node, address indexed owner, address snitch, uint256 snitchPenalty);
event FeesCollected(uint indexed fees, address indexed owner);

struct Snitch {
address addr;
Expand Down Expand Up @@ -93,18 +98,20 @@ contract HNSRegistrar {
* @dev Claims a name by proving ownership of its HNS equivalent.
* Chainlink node verifies that NS record is pointed to namespace of this contract (Ethereum)
* and pulls TXT record with address to give ownership to.
* @param node The HNS domain to claim
* @param tld The HNS domain to claim
*/
function register(bytes32 node) public returns (uint id) {
function register(string calldata tld) public returns (bool) {
bytes32 node = _getNamehash(tld);
require(tldDeposits[node] >= minTLDDeposit, 'Insufficient deposit for TLD');
address tldOwner = IXNHNSOracle(xnhnsOracle).getTLDOwner(node);
require(tldOwner != address(0), 'Invalid TLD in namespace');
require(tldOwner == msg.sender, 'Only TLD owner can register');

Root nftld = _getRoot();
nftld.register(uint(node), tldOwner);
nftld.register(_getLabel(tld), tldOwner);
emit NewOwner(node, tldOwner);
return uint(node);

return true;
}

function increaseDeposit(bytes32 node, uint256 amount) public payable returns (bool) {
Expand Down Expand Up @@ -137,7 +144,8 @@ contract HNSRegistrar {
return IXNHNSOracle(xnhnsOracle).requestTLDUpdate(tld);
}

function claimSnitchReward(bytes32 node) public returns (bool) {
function claimSnitchReward(string calldata tld) public returns (bool) {
bytes32 node = _getNamehash(tld);
(address addr, uint256 startTime) = _getSnitch(node);
// prevent snitch front running oracle response
require(block.timestamp > startTime.add(2 hours), 'Cant snitch yet');
Expand All @@ -146,7 +154,7 @@ contract HNSRegistrar {
address owner = _getRoot().ownerOf(uint(node));
if(IXNHNSOracle(xnhnsOracle).getTLDOwner(node) == address(0)) {
// snitch successful
uint256 tldDeposit = _unregister(node);
uint256 tldDeposit = _unregister(tld);
totalDeposits = totalDeposits.sub( snitchDeposit.add(tldDeposit) );
payable(addr).transfer( snitchDeposit.add(tldDeposit.div(2)) );
emit SnitchedOn(node, owner, addr, tldDeposit.div(2));
Expand All @@ -159,30 +167,32 @@ contract HNSRegistrar {
}
}

function unregister(bytes32 node) public payable {
function unregister(string calldata tld) public payable {
bytes32 node = _getNamehash(tld);
uint id = uint(node);
address owner = _getRoot().ownerOf(id);
require(msg.sender == owner, 'Only NFTLD owner can unregister');

uint256 deposit = _unregister(node);
uint256 deposit = _unregister(tld);
payable(owner).transfer(deposit);
}

function _unregister(bytes32 node) internal returns (uint256 deposit) {
_getRoot().unregister(uint(node));
deposit = tldDeposits[node];
delete tldDeposits[node];
function _unregister(string memory tld) internal returns (uint256 deposit) {
_getRoot().unregister(_getLabel(tld));
deposit = tldDeposits[_getNamehash(tld)];
delete tldDeposits[_getNamehash(tld)];
totalDeposits = totalDeposits.sub(deposit);
return deposit;
}

/**
* @dev donate fees collected by registrar to HNS Fund via Panvala League
*/
function donateProfits() public returns(uint) {
function claimFees() external returns(bool) {
uint feesCollected = address(this).balance.sub(totalDeposits) ;
// hnsFund.regenerate.value(feesCollected)(feesCollected);
return feesCollected;
payable(_getRoot().owner()).call{value: feesCollected};
emit FeesCollected(feesCollected, _getRoot().owner());
return true;
}

/** Getter Functions */
Expand All @@ -194,28 +204,34 @@ contract HNSRegistrar {
function namespace() public view returns (string memory) {
return NAMESPACE;
}

function getLabel(string memory tld) external pure returns (bytes32) {
return _getLabel(tld);
}
function _getLabel(string memory tld) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(tld));
}

function _getNamehash(string memory tld) public pure returns (bytes32) {
return keccak256(abi.encodePacked(
bytes32(0),
keccak256(abi.encodePacked(tld))
));
function getNamehash(string memory tld) external pure returns (bytes32) {
return _getNamehash(tld);
}
function _getNamehash(string memory tld) internal pure returns (bytes32) {
return keccak256(abi.encodePacked( ROOT_NODE, _getLabel(tld) ));
}

function _getRoot() internal view returns (Root) {
return Root(ens.owner(bytes32(0)));
return Root(ens.owner(ROOT_NODE));
}

function _getSnitch(bytes32 node) public view returns (address, uint256) {
Snitch memory _snitch = snitches[node];
return (_snitch.addr, _snitch.startTime);
}

function _registrarEnabled() internal returns (bool) {
function _registrarEnabled() internal view returns (bool) {
return IXNHNSOracle(xnhnsOracle).getCallerPermission(address(this));
}


function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
return interfaceID == INTERFACE_META_ID ||
interfaceID == XNHNS_CLAIM_ID;
Expand Down
Empty file.
2 changes: 2 additions & 0 deletions packages/hardhat/contracts/utils/Controllable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.7.0;
import "@openzeppelin/contracts/access/Ownable.sol";

contract Controllable is Ownable {
// TODO change so its address -> bytes32 and we can scope controllers to specific domains
mapping(address=>bool) public controllers;

event ControllerChanged(address indexed controller, bool enabled);
Expand All @@ -13,6 +14,7 @@ contract Controllable is Ownable {
}

function setController(address controller, bool enabled) public onlyOwner {
// TODO check address is owner of node
controllers[controller] = enabled;
emit ControllerChanged(controller, enabled);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/hardhat/interfaces/IXNHNSOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ interface IXNHNSOracle {

function requestTLDUpdate(string calldata tld) external returns (bytes32);
function receiveTLDUpdate(bytes32, address) external returns (bool);
function getTLDOwner(bytes32 node) external returns (address);
function getCallerPermission(address addr) external returns (bool);
function getTLDOwner(bytes32 node) external view returns (address);
function getCallerPermission(address addr) external view returns (bool);
function setCallerPermission(address addr, bool permission) external returns (bool);
function setOracle(address oracle, uint fee, bytes32 jobId) external returns (bool);
}

0 comments on commit ad66cb8

Please sign in to comment.