-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathOfferingFactory.sol
More file actions
109 lines (95 loc) · 3.69 KB
/
OfferingFactory.sol
File metadata and controls
109 lines (95 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@ensdomains/ens-contracts/contracts/registry/ENSRegistry.sol";
import "@ensdomains/ens-contracts/contracts/ethregistrar/BaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./OfferingRegistry.sol";
import "./strings.sol";
/**
* @title OfferingFactory
* @dev Base contract factory for creating new offerings
*/
abstract contract OfferingFactory is IERC721Receiver {
using strings for *;
ENSRegistry public ens;
OfferingRegistry public offeringRegistry;
// Hardcoded namehash of "eth"
bytes32 public constant rootNode = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;
/**
* @dev Modifier to make a function callable only by the ENS EthRegistrar
*/
modifier onlyRegistrar {
require(msg.sender == ens.owner(rootNode));
_;
}
constructor(
ENSRegistry _ens,
OfferingRegistry _offeringRegistry
) {
ens = _ens;
offeringRegistry = _offeringRegistry;
}
/**
* @dev Registers new subname offering to OfferingRegistry
* Must check if creator of offering is actual owner of ENS name
* @param node bytes32 ENS node
* @param labelHash bytes32 ENS labelhash
* @param newOffering address The address of new offering
* @param version uint The version of offering contract
*/
function registerSubnameOffering(bytes32 node, bytes32 labelHash, address newOffering, uint version)
internal
{
require(ens.owner(node) == msg.sender);
offeringRegistry.addOffering(newOffering, node, msg.sender, version);
}
/**
* @dev Registers new top level name offering to OfferingRegistry
* Checks we own the name already and passes it to the offering
* @param node bytes32 ENS node
* @param labelHash bytes32 ENS labelhash
* @param newOffering address The address of new offering
* @param version uint The version of offering contract
* @param originalOwner address The original owner of the name
*/
function registerTLDOffering(
bytes32 node,
bytes32 labelHash,
address newOffering,
uint version,
address originalOwner
)
internal
{
require(node == keccak256(abi.encodePacked(rootNode, labelHash)));
BaseRegistrar registrar = BaseRegistrar(ens.owner(rootNode));
uint256 tokenId = uint256(labelHash);
address tokenOwner = registrar.ownerOf(tokenId);
require(msg.sender == address(registrar) && tokenOwner == address(this));
registrar.reclaim(tokenId, newOffering);
registrar.transferFrom(tokenOwner, newOffering, tokenId);
offeringRegistry.addOffering(newOffering, node, originalOwner, version);
}
/**
* @dev Namehash function used by ENS to convert plain text name into node hash
* @param name string Plaintext ENS name
* @return bytes32 ENS node hash, aka node
*/
function namehash(string memory name) internal returns(bytes32) {
strings.slice memory nameSlice = name.toSlice();
bytes32 result = bytes32(0);
while (nameSlice.len() > 0) {
bytes memory label = abi.encodePacked(nameSlice.rsplit(".".toSlice()).toString());
result = keccak256(abi.encodePacked(result, keccak256(label)));
}
return result;
}
/**
* @dev Calculates labelHash of ENS name
* @param name string Plaintext ENS name
* @return bytes32 ENS labelHash, hashed label of the name
*/
function getLabelHash(string memory name) internal pure returns(bytes32) {
return keccak256(abi.encodePacked(name.toSlice().split(".".toSlice()).toString()));
}
}