编译器
0.8.13+commit.abaa5c0e
文件 1 的 21:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 21:BytesUtil.sol
pragma solidity >=0.8.4;
library BytesUtils {
function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) {
require(offset + len <= self.length);
assembly {
ret := keccak256(add(add(self, 32), offset), len)
}
}
function namehash(bytes memory self, uint offset) internal pure returns(bytes32) {
(bytes32 labelhash, uint newOffset) = readLabel(self, offset);
if(labelhash == bytes32(0)) {
require(offset == self.length - 1, "namehash: Junk at end of name");
return bytes32(0);
}
return keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));
}
function readLabel(bytes memory self, uint256 idx) internal pure returns (bytes32 labelhash, uint newIdx) {
require(idx < self.length, "readLabel: Index out of bounds");
uint len = uint(uint8(self[idx]));
if(len > 0) {
labelhash = keccak(self, idx + 1, len);
} else {
labelhash = bytes32(0);
}
newIdx = idx + len + 1;
}
}
文件 3 的 21:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 21:Controllable.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
contract Controllable is Ownable {
mapping(address=>bool) public controllers;
event ControllerChanged(address indexed controller, bool active);
function setController(address controller, bool active) onlyOwner() public {
controllers[controller] = active;
emit ControllerChanged(controller, active);
}
modifier onlyController() {
require(controllers[msg.sender], "Controllable: Caller is not a controller");
_;
}
}
文件 5 的 21:ERC1155Fuse.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import "@openzeppelin/contracts/utils/Address.sol";
error OperationProhibited(bytes32 node);
abstract contract ERC1155Fuse is ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
mapping(uint256 => uint256) public _tokens;
mapping(address => mapping(address => bool)) private _operatorApprovals;
function ownerOf(uint256 id) public view virtual returns (address) {
(address owner, , ) = getData(id);
return owner;
}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC165, IERC165)
returns (bool)
{
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address account, uint256 id)
public
view
virtual
override
returns (uint256)
{
require(
account != address(0),
"ERC1155: balance query for the zero address"
);
(address owner, , ) = getData(id);
if (owner == account) {
return 1;
}
return 0;
}
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(
accounts.length == ids.length,
"ERC1155: accounts and ids length mismatch"
);
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
function setApprovalForAll(address operator, bool approved)
public
virtual
override
{
require(
msg.sender != operator,
"ERC1155: setting approval status for self"
);
_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function isApprovedForAll(address account, address operator)
public
view
virtual
override
returns (bool)
{
return _operatorApprovals[account][operator];
}
function getData(uint256 tokenId)
public
view
returns (
address owner,
uint32 fuses,
uint64 expiry
)
{
uint256 t = _tokens[tokenId];
owner = address(uint160(t));
expiry = uint64(t >> 192);
if (block.timestamp > expiry) {
fuses = 0;
} else {
fuses = uint32(t >> 160);
}
}
function _setData(
uint256 tokenId,
address owner,
uint32 fuses,
uint64 expiry
) internal virtual {
_tokens[tokenId] =
uint256(uint160(owner)) |
(uint256(fuses) << 160) |
(uint256(expiry) << 192);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == msg.sender || isApprovedForAll(from, msg.sender),
"ERC1155: caller is not owner nor approved"
);
_transfer(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
ids.length == amounts.length,
"ERC1155: ids and amounts length mismatch"
);
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == msg.sender || isApprovedForAll(from, msg.sender),
"ERC1155: transfer caller is not owner nor approved"
);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
(address oldOwner, uint32 fuses, uint64 expiration) = getData(id);
if (!_canTransfer(fuses)) {
revert OperationProhibited(bytes32(id));
}
require(
amount == 1 && oldOwner == from,
"ERC1155: insufficient balance for transfer"
);
_setData(id, to, fuses, expiration);
}
emit TransferBatch(msg.sender, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(
msg.sender,
from,
to,
ids,
amounts,
data
);
}
function _canTransfer(uint32 fuses) internal virtual returns (bool);
function _mint(
bytes32 node,
address newOwner,
uint32 fuses,
uint64 expiry
) internal virtual {
uint256 tokenId = uint256(node);
address owner = ownerOf(tokenId);
require(owner == address(0), "ERC1155: mint of existing token");
require(newOwner != address(0), "ERC1155: mint to the zero address");
require(
newOwner != address(this),
"ERC1155: newOwner cannot be the NameWrapper contract"
);
_setData(tokenId, newOwner, fuses, expiry);
emit TransferSingle(msg.sender, address(0x0), newOwner, tokenId, 1);
_doSafeTransferAcceptanceCheck(
msg.sender,
address(0),
newOwner,
tokenId,
1,
""
);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ownerOf(tokenId);
_setData(tokenId, address(0x0), 0, 0);
emit TransferSingle(msg.sender, owner, address(0x0), tokenId, 1);
}
function _transfer(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal {
(address oldOwner, uint32 fuses, uint64 expiry) = getData(id);
if (oldOwner == to) {
return;
}
if (!_canTransfer(fuses)) {
revert OperationProhibited(bytes32(id));
}
require(
amount == 1 && oldOwner == from,
"ERC1155: insufficient balance for transfer"
);
_setData(id, to, fuses, expiry);
emit TransferSingle(msg.sender, from, to, id, amount);
_doSafeTransferAcceptanceCheck(msg.sender, from, to, id, amount, data);
}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try
IERC1155Receiver(to).onERC1155Received(
operator,
from,
id,
amount,
data
)
returns (bytes4 response) {
if (
response != IERC1155Receiver(to).onERC1155Received.selector
) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try
IERC1155Receiver(to).onERC1155BatchReceived(
operator,
from,
ids,
amounts,
data
)
returns (bytes4 response) {
if (
response !=
IERC1155Receiver(to).onERC1155BatchReceived.selector
) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
}
文件 6 的 21:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 7 的 21:IBaseRegistrar.sol
import "../registry/TDNS.sol";
import "./IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IBaseRegistrar is IERC721 {
event ControllerAdded(address indexed controller);
event ControllerRemoved(address indexed controller);
event NameMigrated(
uint256 indexed id,
address indexed owner,
uint256 expires
);
event NameRegistered(
uint256 indexed id,
address indexed owner,
uint256 expires
);
event NameRenewed(uint256 indexed id, uint256 expires);
function addController(address controller) external;
function removeController(address controller) external;
function setResolver(address resolver) external;
function nameExpires(uint256 id) external view returns (uint256);
function available(uint256 id) external view returns (bool);
function register(
uint256 id,
address owner,
uint256 duration
) external returns (uint256);
function renew(uint256 id, uint256 duration) external returns (uint256);
function reclaim(uint256 id, address owner) external;
function tokenURI(uint256 tokenId) external view returns(string memory);
}
文件 8 的 21:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 9 的 21:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 10 的 21:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 11 的 21:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 12 的 21:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 13 的 21:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 14 的 21:IETHRegistrarController.sol
pragma solidity >=0.8.4;
import "./IPriceOracle.sol";
interface IETHRegistrarController {
struct domain{
string name;
string tld;
}
function rentPrice(string memory, uint256, bytes32)
external
returns (IPriceOracle.Price memory);
function NODES(string memory)
external
returns (bytes32);
function available(string memory, string memory) external returns (bool);
function makeCommitment(
domain calldata,
address,
uint256,
bytes32,
address,
bytes[] calldata,
bool,
uint32
) external returns (bytes32);
function commit(bytes32) external;
function register(
domain calldata,
address,
uint256,
bytes32,
address,
bytes[] calldata,
bool,
uint32,
uint64
) external payable;
function renew(string calldata, uint256,string calldata tld) external payable;
}
文件 15 的 21:IMetadataService.sol
pragma solidity >=0.8.4;
interface IMetadataService {
function uri(uint256) external view returns (string memory);
}
文件 16 的 21:INameWrapper.sol
pragma solidity ^0.8.4;
import "../registry/TDNS.sol";
import "../ethregistrar/IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "./IMetadataService.sol";
import "../ethregistrar/IETHRegistrarController.sol";
uint32 constant CANNOT_UNWRAP = 1;
uint32 constant CANNOT_BURN_FUSES = 2;
uint32 constant CANNOT_TRANSFER = 4;
uint32 constant CANNOT_SET_RESOLVER = 8;
uint32 constant CANNOT_SET_TTL = 16;
uint32 constant CANNOT_CREATE_SUBDOMAIN = 32;
uint32 constant PARENT_CANNOT_CONTROL = 64;
uint32 constant CAN_DO_EVERYTHING = 0;
interface INameWrapper is IERC1155 {
event NameWrapped(
bytes32 indexed node,
bytes name,
address owner,
uint32 fuses,
uint64 expiry
);
event NameUnwrapped(bytes32 indexed node, address owner);
event FusesSet(bytes32 indexed node, uint32 fuses, uint64 expiry);
function tdns() external view returns (TDNS);
function registrar() external view returns (IBaseRegistrar);
function names(bytes32) external view returns (bytes memory);
function wrap(
bytes calldata name,
address wrappedOwner,
address resolver
) external;
function wrapETH2LD(
string calldata label,
address wrappedOwner,
uint32 fuses,
address resolver,
string calldata tld
) external returns (uint64 expiry);
function registerAndWrapETH2LD(
IETHRegistrarController.domain calldata name,
address wrappedOwner,
uint256 duration,
address resolver,
uint256 amount
) external returns (uint256 registrarExpiry);
function renew(
uint256 labelHash,
uint256 duration
) external returns (uint256 expires);
function unwrap(
bytes32 node,
bytes32 label,
address owner
) external;
function unwrapETH2LD(
bytes32 label,
address newRegistrant,
address newController,
string calldata tld
) external;
function setFuses(bytes32 node, uint32 fuses)
external
returns (uint32 newFuses);
function setChildFuses(
bytes32 parentNode,
bytes32 labelhash,
uint32 fuses,
uint64 expiry
) external;
function setSubnodeRecord(
bytes32 node,
string calldata label,
address owner,
address resolver,
uint64 ttl,
uint32 fuses,
uint64 expiry
) external;
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwner(
bytes32 node,
string calldata label,
address newOwner,
uint32 fuses,
uint64 expiry
) external returns (bytes32);
function isTokenOwnerOrApproved(bytes32 node, address addr)
external
returns (bool);
function setResolver(bytes32 node, address resolver) external;
function setTTL(bytes32 node, uint64 ttl) external;
function ownerOf(uint256 id) external returns (address owner);
function getFuses(bytes32 node)
external
returns (uint32 fuses, uint64 expiry);
function allFusesBurned(bytes32 node, uint32 fuseMask)
external
view
returns (bool);
function addTld(string calldata tld, bytes32 namehash) external;
function removeTld(string calldata tld) external;
}
文件 17 的 21:INameWrapperUpgrade.sol
pragma solidity ^0.8.13;
interface INameWrapperUpgrade {
function setSubnodeRecord(
bytes32 node,
string calldata label,
address owner,
address resolver,
uint64 ttl,
uint32 fuses,
uint64 expiry
) external;
function wrapETH2LD(
string calldata label,
address wrappedOwner,
uint32 fuses,
uint64 expiry,
address resolver
) external;
}
文件 18 的 21:IPriceOracle.sol
pragma solidity >=0.8.4;
interface IPriceOracle {
struct Price {
uint256 base;
uint256 premium;
}
function price(
string calldata name,
uint256 expires,
uint256 duration,
bytes32 namehash
) external view returns (Price calldata);
function setPrice(bytes32 namehash, uint256 price_) external;
}
文件 19 的 21:NameWrapper.sol
pragma solidity ^0.8.4;
import "./ERC1155Fuse.sol";
import "./Controllable.sol";
import "./INameWrapper.sol";
import "./INameWrapperUpgrade.sol";
import "./IMetadataService.sol";
import "../registry/TDNS.sol";
import "../ethregistrar/IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./BytesUtil.sol";
error Unauthorised(bytes32 node, address addr);
error NameNotFound();
error IncompatibleParent();
error IncompatibleName(bytes name);
error IncorrectTokenType();
error LabelMismatch(bytes32 labelHash, bytes32 expectedLabelhash);
error LabelTooShort();
error LabelTooLong(string label);
error IncorrectTargetOwner(address owner);
error CannotUpgrade();
error InvalidExpiry(bytes32 node, uint64 expiry);
interface IAuction {
function setOnAuction(address payable _minter, uint256 _tokenId, string memory label, bytes32 labelhash , string memory tld , uint256 amount) external;
}
contract NameWrapper is
Ownable,
ERC1155Fuse,
INameWrapper,
Controllable,
IERC721Receiver
{
using BytesUtils for bytes;
TDNS public immutable override tdns;
IBaseRegistrar public immutable override registrar;
mapping(bytes32 => bytes) public override names;
IAuction public auction;
bytes32 private constant ROOT_NODE =
0x0000000000000000000000000000000000000000000000000000000000000000;
uint64 private constant GRACE_PERIOD = 90 days;
mapping(string => bytes32) private NODES;
string[] public tlds;
INameWrapperUpgrade public upgradeContract;
uint64 private constant MAX_EXPIRY = type(uint64).max;
constructor(
TDNS _tdns,
IBaseRegistrar _registrar
) {
tdns = _tdns;
registrar = _registrar;
NODES["tomi"] = 0x7bb8237b54e801cf108eb3efb5a3d06b2366985979ad8184e49263d2a74e6fd4;
NODES["com"] = 0xac2c11ea5d4a4826f418d3befbf0537de7f13572d2a433edfe4a7314ea5dc896;
tlds.push("tomi");
tlds.push("com");
_setData(
uint256(NODES["tomi"]),
address(0),
uint32(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP),
MAX_EXPIRY
);
_setData(
uint256(NODES["com"]),
address(0),
uint32(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP),
MAX_EXPIRY
);
_setData(
uint256(ROOT_NODE),
address(0),
uint32(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP),
MAX_EXPIRY
);
names[ROOT_NODE] = "\x00";
names[NODES["tomi"]] = "\x04tomi\x00";
names[NODES["com"]] = "\x03com\x00";
}
function addTld(string calldata tld, bytes32 namehash) external onlyController{
NODES[tld] = namehash;
tlds.push(tld);
_setData(
uint256(NODES[tld]),
address(0),
uint32(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP),
MAX_EXPIRY
);
}
function removeTld(string calldata tld) external onlyController{
NODES[tld] = bytes32(0);
for(uint256 i = 0; i< tlds.length; i++){
if(keccak256(abi.encodePacked(tld)) == keccak256(abi.encodePacked(tlds[i]))){
tlds[i] = tlds[tlds.length-1];
tlds.pop();
}
}
}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC1155Fuse, IERC165)
returns (bool)
{
return
interfaceId == type(INameWrapper).interfaceId ||
super.supportsInterface(interfaceId);
}
function ownerOf(uint256 id)
public
view
override(ERC1155Fuse, INameWrapper)
returns (address owner)
{
return super.ownerOf(id);
}
function setAuction(IAuction _auction) external onlyOwner {
auction = _auction;
}
function uri(uint256 tokenId) public view override returns (string memory) {
return registrar.tokenURI(tokenId);
}
function setUpgradeContract(INameWrapperUpgrade _upgradeAddress)
public
onlyOwner
{
if (address(upgradeContract) != address(0)) {
registrar.setApprovalForAll(address(upgradeContract), false);
tdns.setApprovalForAll(address(upgradeContract), false);
}
upgradeContract = _upgradeAddress;
if (address(upgradeContract) != address(0)) {
registrar.setApprovalForAll(address(upgradeContract), true);
tdns.setApprovalForAll(address(upgradeContract), true);
}
}
modifier onlyTokenOwner(bytes32 node) {
if (!isTokenOwnerOrApproved(node, msg.sender)) {
revert Unauthorised(node, msg.sender);
}
_;
}
function isTokenOwnerOrApproved(bytes32 node, address addr)
public
view
override
returns (bool)
{
address owner = ownerOf(uint256(node));
return owner == addr || isApprovedForAll(owner, addr);
}
function getFuses(bytes32 node)
public
view
override
returns (uint32 fuses, uint64 expiry)
{
(, fuses, expiry) = getData(uint256(node));
if (fuses == 0 && expiry == 0) {
bytes memory name = names[node];
if (name.length == 0) {
revert NameNotFound();
}
}
}
function wrapETH2LD(
string calldata label,
address wrappedOwner,
uint32 fuses,
address resolver,
string calldata tld
) public override returns (uint64 expiry) {
require(NODES[tld] != bytes32(0) , "TLD not supported");
bytes32 labelhash = keccak256(bytes(label));
bytes32 node = _makeNode(NODES[tld], labelhash);
uint256 tokenId = uint256(node);
address registrant = registrar.ownerOf(tokenId);
if (
registrant != msg.sender &&
!isApprovedForAll(registrant, msg.sender) &&
!registrar.isApprovedForAll(registrant, msg.sender)
) {
revert Unauthorised(
bytes32(tokenId),
msg.sender
);
}
registrar.transferFrom(registrant, address(this), tokenId);
registrar.reclaim(tokenId, address(this));
expiry = uint64(registrar.nameExpires(tokenId)) + GRACE_PERIOD;
return _wrapETH2LD(label, wrappedOwner, fuses, expiry, resolver, tld);
}
function registerAndWrapETH2LD(
IETHRegistrarController.domain calldata name,
address wrappedOwner,
uint256 duration,
address resolver,
uint256 amount
) external override onlyController returns (uint256 registrarExpiry) {
bytes32 labelhash = keccak256(bytes(name.name));
bytes32 node = _makeNode(NODES[name.tld], labelhash);
uint256 tokenId = uint256(node);
_addLabel(name.name, names[NODES[name.tld]]);
registrarExpiry = registrar.register(tokenId, address(this), duration);
tdns.setResolver(node, resolver);
registrar.transferFrom(address(this), address(auction), tokenId);
auction.setOnAuction(payable(wrappedOwner), tokenId, name.name, labelhash, name.tld , amount);
}
function renew(
uint256 tokenId,
uint256 duration
) external override onlyController returns (uint256 expires) {
bytes32 node = bytes32(tokenId);
uint256 registrarExpiry = registrar.renew(tokenId, duration);
try registrar.ownerOf(tokenId) returns (address registrarOwner) {
if (
registrarOwner != address(this) ||
tdns.owner(node) != address(this)
) {
return registrarExpiry;
}
} catch {
return registrarExpiry;
}
(address owner, uint32 fuses,) = getData(
uint256(node)
);
uint64 expiry = uint64(registrarExpiry) + GRACE_PERIOD;
_setData(node, owner, fuses, expiry);
return registrarExpiry;
}
function wrap(
bytes calldata name,
address wrappedOwner,
address resolver
) public override {
(bytes32 labelhash, uint256 offset) = name.readLabel(0);
bytes32 parentNode = name.namehash(offset);
bytes32 node = _makeNode(parentNode, labelhash);
bool parentNodeBool = false;
for(uint256 i = 0; i < tlds.length; i++){
if(parentNode == NODES[tlds[i]]){
parentNodeBool = true;
break;
}
}
if (parentNodeBool) {
revert IncompatibleParent();
}
address owner = tdns.owner(node);
if (
owner != msg.sender &&
!isApprovedForAll(owner, msg.sender) &&
!tdns.isApprovedForAll(owner, msg.sender)
) {
revert Unauthorised(node, msg.sender);
}
if (resolver != address(0)) {
tdns.setResolver(node, resolver);
}
tdns.setOwner(node, address(this));
_wrap(node, name, wrappedOwner, 0, 0);
}
function unwrapETH2LD(
bytes32 labelhash,
address newRegistrant,
address newController,
string calldata tld
) public override onlyTokenOwner(_makeNode(NODES[tld], labelhash)) {
require(NODES[tld] != bytes32(0) , "TLD not supported");
bytes32 node = _makeNode(NODES[tld], labelhash);
_unwrap(node, newController);
registrar.transferFrom(
address(this),
newRegistrant,
uint256(node)
);
}
function unwrap(
bytes32 parentNode,
bytes32 labelhash,
address newController
) public override onlyTokenOwner(_makeNode(parentNode, labelhash)) {
bool parentNodeBool = false;
for(uint256 i = 0; i < tlds.length; i++){
if(parentNode == NODES[tlds[i]]){
parentNodeBool = true;
break;
}
}
if (parentNodeBool) {
revert IncompatibleParent();
}
_unwrap(_makeNode(parentNode, labelhash), newController);
}
function setFuses(bytes32 node, uint32 fuses)
public
onlyTokenOwner(node)
operationAllowed(node, CANNOT_BURN_FUSES)
returns (uint32)
{
if (fuses & PARENT_CANNOT_CONTROL != 0) {
revert Unauthorised(node, msg.sender);
}
(address owner, uint32 oldFuses, uint64 expiry) = getData(
uint256(node)
);
fuses |= oldFuses;
_setFuses(node, owner, fuses, expiry);
return fuses;
}
function upgradeETH2LD(
string calldata label,
address wrappedOwner,
address resolver,
string calldata tld
) public {
bytes32 labelhash = keccak256(bytes(label));
bytes32 node = _makeNode(NODES[tld], labelhash);
(uint32 fuses, uint64 expiry) = _prepareUpgrade(node);
upgradeContract.wrapETH2LD(
label,
wrappedOwner,
fuses,
expiry,
resolver
);
}
function upgrade(
bytes32 parentNode,
string calldata label,
address wrappedOwner,
address resolver
) public {
bytes32 labelhash = keccak256(bytes(label));
bytes32 node = _makeNode(parentNode, labelhash);
(uint32 fuses, uint64 expiry) = _prepareUpgrade(node);
upgradeContract.setSubnodeRecord(
parentNode,
label,
wrappedOwner,
resolver,
0,
fuses,
expiry
);
}
function setChildFuses(
bytes32 parentNode,
bytes32 labelhash,
uint32 fuses,
uint64 expiry
) public {
bytes32 node = _makeNode(parentNode, labelhash);
(address owner, uint32 oldFuses, uint64 oldExpiry) = getData(
uint256(node)
);
uint64 maxExpiry;
bool parentNodeBool = false;
for(uint256 i = 0; i < tlds.length; i++){
if(parentNode == NODES[tlds[i]]){
parentNodeBool = true;
break;
}
}
if (parentNodeBool) {
if (!isTokenOwnerOrApproved(node, msg.sender)) {
revert Unauthorised(node, msg.sender);
}
maxExpiry = uint64(registrar.nameExpires(uint256(node)));
} else {
if (!isTokenOwnerOrApproved(parentNode, msg.sender)) {
revert Unauthorised(node, msg.sender);
}
(, , maxExpiry) = getData(uint256(parentNode));
}
expiry = _normaliseExpiry(expiry, oldExpiry, maxExpiry);
if (
oldFuses & PARENT_CANNOT_CONTROL != 0 &&
oldFuses | fuses != oldFuses
) {
revert OperationProhibited(node);
}
fuses |= oldFuses;
_setFuses(node, owner, fuses, expiry);
}
function setSubnodeOwner(
bytes32 parentNode,
string calldata label,
address newOwner,
uint32 fuses,
uint64 expiry
)
public
onlyTokenOwner(parentNode)
canCallSetSubnodeOwner(parentNode, keccak256(bytes(label)))
returns (bytes32 node)
{
bytes32 labelhash = keccak256(bytes(label));
node = _makeNode(parentNode, labelhash);
(, , expiry) = _getDataAndNormaliseExpiry(parentNode, node, expiry);
if (tdns.owner(node) != address(this)) {
tdns.setSubnodeOwner(parentNode, labelhash, address(this));
_addLabelAndWrap(parentNode, node, label, newOwner, fuses, expiry);
} else {
_transferAndBurnFuses(node, newOwner, fuses, expiry);
}
}
function setSubnodeRecord(
bytes32 parentNode,
string memory label,
address newOwner,
address resolver,
uint64 ttl,
uint32 fuses,
uint64 expiry
)
public
onlyTokenOwner(parentNode)
canCallSetSubnodeOwner(parentNode, keccak256(bytes(label)))
{
bytes32 labelhash = keccak256(bytes(label));
bytes32 node = _makeNode(parentNode, labelhash);
(, , expiry) = _getDataAndNormaliseExpiry(parentNode, node, expiry);
if (tdns.owner(node) != address(this)) {
tdns.setSubnodeRecord(
parentNode,
labelhash,
address(this),
resolver,
ttl
);
_addLabelAndWrap(parentNode, node, label, newOwner, fuses, expiry);
} else {
tdns.setSubnodeRecord(
parentNode,
labelhash,
address(this),
resolver,
ttl
);
_transferAndBurnFuses(node, newOwner, fuses, expiry);
}
}
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
)
public
override
onlyTokenOwner(node)
operationAllowed(
node,
CANNOT_TRANSFER | CANNOT_SET_RESOLVER | CANNOT_SET_TTL
)
{
tdns.setRecord(node, address(this), resolver, ttl);
(address oldOwner, , ) = getData(uint256(node));
_transfer(oldOwner, owner, uint256(node), 1, "");
}
function setResolver(bytes32 node, address resolver)
public
override
onlyTokenOwner(node)
operationAllowed(node, CANNOT_SET_RESOLVER)
{
tdns.setResolver(node, resolver);
}
function setTTL(bytes32 node, uint64 ttl)
public
override
onlyTokenOwner(node)
operationAllowed(node, CANNOT_SET_TTL)
{
tdns.setTTL(node, ttl);
}
modifier operationAllowed(bytes32 node, uint32 fuseMask) {
(, uint32 fuses, ) = getData(uint256(node));
if (fuses & fuseMask != 0) {
revert OperationProhibited(node);
}
_;
}
modifier canCallSetSubnodeOwner(bytes32 node, bytes32 labelhash) {
bytes32 subnode = _makeNode(node, labelhash);
address owner = tdns.owner(subnode);
if (owner == address(0)) {
(, uint32 fuses, ) = getData(uint256(node));
if (fuses & CANNOT_CREATE_SUBDOMAIN != 0) {
revert OperationProhibited(node);
}
} else {
(, uint32 subnodeFuses, ) = getData(uint256(subnode));
if (subnodeFuses & PARENT_CANNOT_CONTROL != 0) {
revert OperationProhibited(node);
}
}
_;
}
function allFusesBurned(bytes32 node, uint32 fuseMask)
public
view
override
returns (bool)
{
(, uint32 fuses, ) = getData(uint256(node));
return fuses & fuseMask == fuseMask;
}
function onERC721Received(
address to,
address,
uint256 tokenId,
bytes calldata data
) public override returns (bytes4) {
if (msg.sender != address(registrar)) {
revert IncorrectTokenType();
}
(
string memory label,
address owner,
uint32 fuses,
uint64 expiry,
address resolver
) = abi.decode(data, (string, address, uint32, uint64, address));
string memory tld = "";
bytes32 node;
for(uint256 i = 0; i < tlds.length; i++){
bytes32 nodeHash = NODES[tlds[i]];
node = _makeNode(nodeHash, keccak256(bytes(label)));
if(uint256(node) == tokenId){
tld = tlds[i];
break;
}
}
if(bytes(tld).length <= 0){
revert IncorrectTokenType();
}
registrar.reclaim(uint256(node), address(this));
_wrapETH2LD(label, owner, fuses, expiry, resolver, tld);
return IERC721Receiver(to).onERC721Received.selector;
}
function _canTransfer(uint32 fuses) internal pure override returns (bool) {
return fuses & CANNOT_TRANSFER == 0;
}
function _makeNode(bytes32 node, bytes32 labelhash)
private
pure
returns (bytes32)
{
return keccak256(abi.encodePacked(node, labelhash));
}
function _addLabel(string memory label, bytes memory name)
internal
pure
returns (bytes memory ret)
{
if (bytes(label).length < 1) {
revert LabelTooShort();
}
if (bytes(label).length > 255) {
revert LabelTooLong(label);
}
return abi.encodePacked(uint8(bytes(label).length), label, name);
}
function _mint(
bytes32 node,
address wrappedOwner,
uint32 fuses,
uint64 expiry
) internal override {
address oldWrappedOwner = ownerOf(uint256(node));
_canFusesBeBurned(node, fuses);
if (oldWrappedOwner != address(0)) {
_burn(uint256(node));
emit NameUnwrapped(node, address(0));
}
super._mint(node, wrappedOwner, fuses, expiry);
}
function _wrap(
bytes32 node,
bytes memory name,
address wrappedOwner,
uint32 fuses,
uint64 expiry
) internal {
names[node] = name;
_mint(node, wrappedOwner, fuses, expiry);
emit NameWrapped(node, name, wrappedOwner, fuses, expiry);
}
function _addLabelAndWrap(
bytes32 parentNode,
bytes32 node,
string memory label,
address newOwner,
uint32 fuses,
uint64 expiry
) internal {
bytes memory name = _addLabel(label, names[parentNode]);
_wrap(node, name, newOwner, fuses, expiry);
}
function _prepareUpgrade(bytes32 node)
private
returns (uint32 fuses, uint64 expiry)
{
if (address(upgradeContract) == address(0)) {
revert CannotUpgrade();
}
if (!isTokenOwnerOrApproved(node, msg.sender)) {
revert Unauthorised(node, msg.sender);
}
(fuses, expiry) = getFuses(node);
_burn(uint256(node));
}
function _transferAndBurnFuses(
bytes32 node,
address newOwner,
uint32 fuses,
uint64 expiry
) internal {
(address owner, , ) = getData(uint256(node));
_transfer(owner, newOwner, uint256(node), 1, "");
_setFuses(node, newOwner, fuses, expiry);
}
function _getDataAndNormaliseExpiry(
bytes32 parentNode,
bytes32 node,
uint64 expiry
)
internal
view
returns (
address owner,
uint32 fuses,
uint64
)
{
uint64 oldExpiry;
(owner, fuses, oldExpiry) = getData(uint256(node));
(, , uint64 maxExpiry) = getData(uint256(parentNode));
expiry = _normaliseExpiry(expiry, oldExpiry, maxExpiry);
return (owner, fuses, expiry);
}
function _getETH2LDDataAndNormaliseExpiry(
bytes32 node,
bytes32 labelhash,
uint64 expiry
)
internal
view
returns (
address owner,
uint32 fuses,
uint64
)
{
uint64 oldExpiry;
(owner, fuses, oldExpiry) = getData(uint256(node));
uint64 maxExpiry = uint64(registrar.nameExpires(uint256(node)));
expiry = _normaliseExpiry(expiry, oldExpiry, maxExpiry);
return (owner, fuses, expiry);
}
function _normaliseExpiry(
uint64 expiry,
uint64 oldExpiry,
uint64 maxExpiry
) internal pure returns (uint64) {
if (expiry > maxExpiry) {
expiry = maxExpiry;
}
if (expiry < oldExpiry) {
expiry = oldExpiry;
}
return expiry;
}
function _wrapETH2LD(
string memory label,
address wrappedOwner,
uint32 fuses,
uint64 expiry,
address resolver,
string memory tld
) private returns (uint64) {
bytes32 labelhash = keccak256(bytes(label));
bytes32 node = _makeNode(NODES[tld], labelhash);
(, , expiry) = _getETH2LDDataAndNormaliseExpiry(
node,
labelhash,
expiry
);
_addLabelAndWrap(
NODES[tld],
node,
label,
wrappedOwner,
fuses | PARENT_CANNOT_CONTROL,
expiry
);
if (resolver != address(0)) {
tdns.setResolver(node, resolver);
}
return expiry;
}
function _unwrap(bytes32 node, address newOwner) private {
if (newOwner == address(0x0) || newOwner == address(this)) {
revert IncorrectTargetOwner(newOwner);
}
if (allFusesBurned(node, CANNOT_UNWRAP)) {
revert OperationProhibited(node);
}
_burn(uint256(node));
tdns.setOwner(node, newOwner);
emit NameUnwrapped(node, newOwner);
}
function _setFuses(
bytes32 node,
address owner,
uint32 fuses,
uint64 expiry
) internal {
_setData(node, owner, fuses, expiry);
emit FusesSet(node, fuses, expiry);
}
function _setData(
bytes32 node,
address owner,
uint32 fuses,
uint64 expiry
) internal {
_canFusesBeBurned(node, fuses);
super._setData(uint256(node), owner, fuses, expiry);
}
function _canFusesBeBurned(bytes32 node, uint32 fuses) internal pure {
if (
fuses & ~PARENT_CANNOT_CONTROL != 0 &&
fuses & (PARENT_CANNOT_CONTROL | CANNOT_UNWRAP) !=
(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP)
) {
revert OperationProhibited(node);
}
}
}
文件 20 的 21:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 21 的 21:TDNS.sol
pragma solidity >=0.8.4;
interface TDNS {
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
event Transfer(bytes32 indexed node, address owner);
event NewResolver(bytes32 indexed node, address resolver);
event NewTTL(bytes32 indexed node, uint64 ttl);
event NewOwnerRegistrar(bytes32 indexed subnode, address owner);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwnerRegistrar(
bytes32 subnode,
address owner
) external returns (bytes32);
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external returns (bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
function isApprovedForAll(address owner, address operator)
external
view
returns (bool);
}
{
"compilationTarget": {
"contracts/wrapper/NameWrapper.sol": "NameWrapper"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract TDNS","name":"_tdns","type":"address"},{"internalType":"contract IBaseRegistrar","name":"_registrar","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotUpgrade","type":"error"},{"inputs":[],"name":"IncompatibleParent","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"IncorrectTargetOwner","type":"error"},{"inputs":[],"name":"IncorrectTokenType","type":"error"},{"inputs":[{"internalType":"string","name":"label","type":"string"}],"name":"LabelTooLong","type":"error"},{"inputs":[],"name":"LabelTooShort","type":"error"},{"inputs":[],"name":"NameNotFound","type":"error"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"OperationProhibited","type":"error"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"addr","type":"address"}],"name":"Unauthorised","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"controller","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"ControllerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"fuses","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"FusesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"NameUnwrapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint32","name":"fuses","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"NameWrapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_tokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tld","type":"string"},{"internalType":"bytes32","name":"namehash","type":"bytes32"}],"name":"addTld","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint32","name":"fuseMask","type":"uint32"}],"name":"allFusesBurned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auction","outputs":[{"internalType":"contract IAuction","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"controllers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getData","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint64","name":"expiry","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"getFuses","outputs":[{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint64","name":"expiry","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"addr","type":"address"}],"name":"isTokenOwnerOrApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"names","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"tld","type":"string"}],"internalType":"struct IETHRegistrarController.domain","name":"name","type":"tuple"},{"internalType":"address","name":"wrappedOwner","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerAndWrapETH2LD","outputs":[{"internalType":"uint256","name":"registrarExpiry","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registrar","outputs":[{"internalType":"contract IBaseRegistrar","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tld","type":"string"}],"name":"removeTld","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"renew","outputs":[{"internalType":"uint256","name":"expires","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IAuction","name":"_auction","type":"address"}],"name":"setAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"internalType":"bytes32","name":"labelhash","type":"bytes32"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"setChildFuses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint32","name":"fuses","type":"uint32"}],"name":"setFuses","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setRecord","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"setSubnodeOwner","outputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"setSubnodeRecord","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setTTL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract INameWrapperUpgrade","name":"_upgradeAddress","type":"address"}],"name":"setUpgradeContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tdns","outputs":[{"internalType":"contract TDNS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tlds","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"internalType":"bytes32","name":"labelhash","type":"bytes32"},{"internalType":"address","name":"newController","type":"address"}],"name":"unwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"},{"internalType":"address","name":"newRegistrant","type":"address"},{"internalType":"address","name":"newController","type":"address"},{"internalType":"string","name":"tld","type":"string"}],"name":"unwrapETH2LD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"wrappedOwner","type":"address"},{"internalType":"address","name":"resolver","type":"address"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upgradeContract","outputs":[{"internalType":"contract INameWrapperUpgrade","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"wrappedOwner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"string","name":"tld","type":"string"}],"name":"upgradeETH2LD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"address","name":"wrappedOwner","type":"address"},{"internalType":"address","name":"resolver","type":"address"}],"name":"wrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"wrappedOwner","type":"address"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"string","name":"tld","type":"string"}],"name":"wrapETH2LD","outputs":[{"internalType":"uint64","name":"expiry","type":"uint64"}],"stateMutability":"nonpayable","type":"function"}]