Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Multi Chain
Multichain Addresses
1 address found via
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 9380462 | 1225 days 21 hrs ago | IN | Create: RegistrarMigration | 0 ETH | 0.00328032 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RegistrarMigration
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-01-30 */ // File: @ensdomains/ens/contracts/ENS.sol pragma solidity >=0.4.24; interface ENS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. 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 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); } // File: @ensdomains/ens/contracts/Deed.sol pragma solidity >=0.4.24; interface Deed { function setOwner(address payable newOwner) external; function setRegistrar(address newRegistrar) external; function setBalance(uint newValue, bool throwOnFailure) external; function closeDeed(uint refundRatio) external; function destroyDeed() external; function owner() external view returns (address); function previousOwner() external view returns (address); function value() external view returns (uint); function creationDate() external view returns (uint); } // File: @ensdomains/ens/contracts/Registrar.sol pragma solidity >=0.4.24; interface Registrar { enum Mode { Open, Auction, Owned, Forbidden, Reveal, NotYetAvailable } event AuctionStarted(bytes32 indexed hash, uint registrationDate); event NewBid(bytes32 indexed hash, address indexed bidder, uint deposit); event BidRevealed(bytes32 indexed hash, address indexed owner, uint value, uint8 status); event HashRegistered(bytes32 indexed hash, address indexed owner, uint value, uint registrationDate); event HashReleased(bytes32 indexed hash, uint value); event HashInvalidated(bytes32 indexed hash, string indexed name, uint value, uint registrationDate); function state(bytes32 _hash) external view returns (Mode); function startAuction(bytes32 _hash) external; function startAuctions(bytes32[] calldata _hashes) external; function newBid(bytes32 sealedBid) external payable; function startAuctionsAndBid(bytes32[] calldata hashes, bytes32 sealedBid) external payable; function unsealBid(bytes32 _hash, uint _value, bytes32 _salt) external; function cancelBid(address bidder, bytes32 seal) external; function finalizeAuction(bytes32 _hash) external; function transfer(bytes32 _hash, address payable newOwner) external; function releaseDeed(bytes32 _hash) external; function invalidateName(string calldata unhashedName) external; function eraseNode(bytes32[] calldata labels) external; function transferRegistrars(bytes32 _hash) external; function acceptRegistrarTransfer(bytes32 hash, Deed deed, uint registrationDate) external; function entries(bytes32 _hash) external view returns (Mode, address, uint, uint, uint); } // File: @ensdomains/subdomain-registrar/contracts/Resolver.sol pragma solidity ^0.5.0; /** * @dev A basic interface for ENS resolvers. */ contract Resolver { function supportsInterface(bytes4 interfaceID) public pure returns (bool); function addr(bytes32 node) public view returns (address); function setAddr(bytes32 node, address addr) public; } // File: @ensdomains/subdomain-registrar/contracts/RegistrarInterface.sol pragma solidity ^0.5.0; contract RegistrarInterface { event OwnerChanged(bytes32 indexed label, address indexed oldOwner, address indexed newOwner); event DomainConfigured(bytes32 indexed label); event DomainUnlisted(bytes32 indexed label); event NewRegistration(bytes32 indexed label, string subdomain, address indexed owner, address indexed referrer, uint price); event RentPaid(bytes32 indexed label, string subdomain, uint amount, uint expirationDate); // InterfaceID of these four methods is 0xc1b15f5a function query(bytes32 label, string calldata subdomain) external view returns (string memory domain, uint signupFee, uint rent, uint referralFeePPM); function register(bytes32 label, string calldata subdomain, address owner, address payable referrer, address resolver) external payable; function rentDue(bytes32 label, string calldata subdomain) external view returns (uint timestamp); function payRent(bytes32 label, string calldata subdomain) external payable; } // File: @ensdomains/subdomain-registrar/contracts/AbstractSubdomainRegistrar.sol pragma solidity ^0.5.0; contract AbstractSubdomainRegistrar is RegistrarInterface { // namehash('eth') bytes32 constant public TLD_NODE = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae; bool public stopped = false; address public registrarOwner; address public migration; address public registrar; ENS public ens; modifier owner_only(bytes32 label) { require(owner(label) == msg.sender); _; } modifier not_stopped() { require(!stopped); _; } modifier registrar_owner_only() { require(msg.sender == registrarOwner); _; } event DomainTransferred(bytes32 indexed label, string name); constructor(ENS _ens) public { ens = _ens; registrar = ens.owner(TLD_NODE); registrarOwner = msg.sender; } function doRegistration(bytes32 node, bytes32 label, address subdomainOwner, Resolver resolver) internal { // Get the subdomain so we can configure it ens.setSubnodeOwner(node, label, address(this)); bytes32 subnode = keccak256(abi.encodePacked(node, label)); // Set the subdomain's resolver ens.setResolver(subnode, address(resolver)); // Set the address record on the resolver resolver.setAddr(subnode, subdomainOwner); // Pass ownership of the new subdomain to the registrant ens.setOwner(subnode, subdomainOwner); } function supportsInterface(bytes4 interfaceID) public pure returns (bool) { return ( (interfaceID == 0x01ffc9a7) // supportsInterface(bytes4) || (interfaceID == 0xc1b15f5a) // RegistrarInterface ); } function rentDue(bytes32 label, string calldata subdomain) external view returns (uint timestamp) { return 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } /** * @dev Sets the resolver record for a name in ENS. * @param name The name to set the resolver for. * @param resolver The address of the resolver */ function setResolver(string memory name, address resolver) public owner_only(keccak256(bytes(name))) { bytes32 label = keccak256(bytes(name)); bytes32 node = keccak256(abi.encodePacked(TLD_NODE, label)); ens.setResolver(node, resolver); } /** * @dev Configures a domain for sale. * @param name The name to configure. * @param price The price in wei to charge for subdomain registrations * @param referralFeePPM The referral fee to offer, in parts per million */ function configureDomain(string memory name, uint price, uint referralFeePPM) public { configureDomainFor(name, price, referralFeePPM, msg.sender, address(0x0)); } /** * @dev Stops the registrar, disabling configuring of new domains. */ function stop() public not_stopped registrar_owner_only { stopped = true; } /** * @dev Sets the address where domains are migrated to. * @param _migration Address of the new registrar. */ function setMigrationAddress(address _migration) public registrar_owner_only { require(stopped); migration = _migration; } function transferOwnership(address newOwner) public registrar_owner_only { registrarOwner = newOwner; } /** * @dev Returns information about a subdomain. * @param label The label hash for the domain. * @param subdomain The label for the subdomain. * @return domain The name of the domain, or an empty string if the subdomain * is unavailable. * @return price The price to register a subdomain, in wei. * @return rent The rent to retain a subdomain, in wei per second. * @return referralFeePPM The referral fee for the dapp, in ppm. */ function query(bytes32 label, string calldata subdomain) external view returns (string memory domain, uint price, uint rent, uint referralFeePPM); function owner(bytes32 label) public view returns (address); function configureDomainFor(string memory name, uint price, uint referralFeePPM, address payable _owner, address _transfer) public; } // File: openzeppelin-solidity/contracts/introspection/IERC165.sol pragma solidity ^0.5.0; /** * @title IERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface IERC165 { /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol pragma solidity ^0.5.0; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract 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) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.5.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safeTransfer`. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public returns (bytes4); } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: openzeppelin-solidity/contracts/utils/Address.sol pragma solidity ^0.5.0; /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: openzeppelin-solidity/contracts/introspection/ERC165.sol pragma solidity ^0.5.0; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor () internal { _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); _supportedInterfaces[interfaceId] = true; } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol pragma solidity ^0.5.0; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721 is ERC165, IERC721 { using SafeMath for uint256; using Address for address; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping (address => uint256) private _ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ constructor () public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0)); return _ownedTokensCount[owner]; } /** * @dev Gets the owner of the specified token ID * @param tokenId uint256 ID of the token to query the owner of * @return owner address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0)); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = ownerOf(tokenId); require(to != owner); require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId)); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != msg.sender); _operatorApprovals[msg.sender][to] = approved; emit ApprovalForAll(msg.sender, to, approved); } /** * @dev Tells whether an operator is approved by a given owner * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address * Usage of this method is discouraged, use `safeTransferFrom` whenever possible * Requires the msg sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom(address from, address to, uint256 tokenId) public { require(_isApprovedOrOwner(msg.sender, tokenId)); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * * Requires the msg sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data)); } /** * @dev Returns whether the specified token exists * @param tokenId uint256 ID of the token to query the existence of * @return whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0)); require(!_exists(tokenId)); _tokenOwner[tokenId] = to; _ownedTokensCount[to] = _ownedTokensCount[to].add(1); emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner); _clearApproval(tokenId); _ownedTokensCount[owner] = _ownedTokensCount[owner].sub(1); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from); require(to != address(0)); _clearApproval(tokenId); _ownedTokensCount[from] = _ownedTokensCount[from].sub(1); _ownedTokensCount[to] = _ownedTokensCount[to].add(1); _tokenOwner[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) internal returns (bool) { if (!to.isContract()) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); return (retval == _ERC721_RECEIVED); } /** * @dev Private function to clear current approval of a given token ID * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * @notice Renouncing to ownership will leave the contract without an owner. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: @ensdomains/ethregistrar/contracts/BaseRegistrar.sol pragma solidity >=0.4.24; contract BaseRegistrar is IERC721, Ownable { uint constant public GRACE_PERIOD = 90 days; event ControllerAdded(address indexed controller); event ControllerRemoved(address indexed controller); event NameMigrated(uint256 indexed id, address indexed owner, uint expires); event NameRegistered(uint256 indexed id, address indexed owner, uint expires); event NameRenewed(uint256 indexed id, uint expires); // The ENS registry ENS public ens; // The namehash of the TLD this registrar owns (eg, .eth) bytes32 public baseNode; // A map of addresses that are authorised to register and renew names. mapping(address=>bool) public controllers; // Authorises a controller, who can register and renew domains. function addController(address controller) external; // Revoke controller permission for an address. function removeController(address controller) external; // Set the resolver for the TLD this registrar manages. function setResolver(address resolver) external; // Returns the expiration timestamp of the specified label hash. function nameExpires(uint256 id) external view returns(uint); // Returns true iff the specified name is available for registration. function available(uint256 id) public view returns(bool); /** * @dev Register a name. */ function register(uint256 id, address owner, uint duration) external returns(uint); function renew(uint256 id, uint duration) external returns(uint); /** * @dev Reclaim ownership of a name in ENS, if you own it in the registrar. */ function reclaim(uint256 id, address owner) external; } // File: @ensdomains/ethregistrar/contracts/BaseRegistrarImplementation.sol pragma solidity ^0.5.0; contract BaseRegistrarImplementation is BaseRegistrar, ERC721 { // A map of expiry times mapping(uint256=>uint) expiries; bytes4 constant private INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)")); bytes4 constant private ERC721_ID = bytes4( keccak256("balanceOf(address)") ^ keccak256("ownerOf(uint256)") ^ keccak256("approve(address,uint256)") ^ keccak256("getApproved(uint256)") ^ keccak256("setApprovalForAll(address,bool)") ^ keccak256("isApprovedForAll(address,address)") ^ keccak256("transferFrom(address,address,uint256)") ^ keccak256("safeTransferFrom(address,address,uint256)") ^ keccak256("safeTransferFrom(address,address,uint256,bytes)") ); bytes4 constant private RECLAIM_ID = bytes4(keccak256("reclaim(uint256,address)")); constructor(ENS _ens, bytes32 _baseNode) public { ens = _ens; baseNode = _baseNode; } modifier live { require(ens.owner(baseNode) == address(this)); _; } modifier onlyController { require(controllers[msg.sender]); _; } /** * @dev Gets the owner of the specified token ID. Names become unowned * when their registration expires. * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { require(expiries[tokenId] > now); return super.ownerOf(tokenId); } // Authorises a controller, who can register and renew domains. function addController(address controller) external onlyOwner { controllers[controller] = true; emit ControllerAdded(controller); } // Revoke controller permission for an address. function removeController(address controller) external onlyOwner { controllers[controller] = false; emit ControllerRemoved(controller); } // Set the resolver for the TLD this registrar manages. function setResolver(address resolver) external onlyOwner { ens.setResolver(baseNode, resolver); } // Returns the expiration timestamp of the specified id. function nameExpires(uint256 id) external view returns(uint) { return expiries[id]; } // Returns true iff the specified name is available for registration. function available(uint256 id) public view returns(bool) { // Not available if it's registered here or in its grace period. return expiries[id] + GRACE_PERIOD < now; } /** * @dev Register a name. * @param id The token ID (keccak256 of the label). * @param owner The address that should own the registration. * @param duration Duration in seconds for the registration. */ function register(uint256 id, address owner, uint duration) external returns(uint) { return _register(id, owner, duration, true); } /** * @dev Register a name, without modifying the registry. * @param id The token ID (keccak256 of the label). * @param owner The address that should own the registration. * @param duration Duration in seconds for the registration. */ function registerOnly(uint256 id, address owner, uint duration) external returns(uint) { return _register(id, owner, duration, false); } function _register(uint256 id, address owner, uint duration, bool updateRegistry) internal live onlyController returns(uint) { require(available(id)); require(now + duration + GRACE_PERIOD > now + GRACE_PERIOD); // Prevent future overflow expiries[id] = now + duration; if(_exists(id)) { // Name was previously owned, and expired _burn(id); } _mint(owner, id); if(updateRegistry) { ens.setSubnodeOwner(baseNode, bytes32(id), owner); } emit NameRegistered(id, owner, now + duration); return now + duration; } function renew(uint256 id, uint duration) external live onlyController returns(uint) { require(expiries[id] + GRACE_PERIOD >= now); // Name must be registered here or in grace period require(expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD); // Prevent future overflow expiries[id] += duration; emit NameRenewed(id, expiries[id]); return expiries[id]; } /** * @dev Reclaim ownership of a name in ENS, if you own it in the registrar. */ function reclaim(uint256 id, address owner) external live { require(_isApprovedOrOwner(msg.sender, id)); ens.setSubnodeOwner(baseNode, bytes32(id), owner); } function supportsInterface(bytes4 interfaceID) external view returns (bool) { return interfaceID == INTERFACE_META_ID || interfaceID == ERC721_ID || interfaceID == RECLAIM_ID; } } // File: @ensdomains/ens/contracts/DeedImplementation.sol pragma solidity ^0.5.0; /** * @title Deed to hold ether in exchange for ownership of a node * @dev The deed can be controlled only by the registrar and can only send ether back to the owner. */ contract DeedImplementation is Deed { address payable constant burn = address(0xdead); address payable private _owner; address private _previousOwner; address private _registrar; uint private _creationDate; uint private _value; bool active; event OwnerChanged(address newOwner); event DeedClosed(); modifier onlyRegistrar { require(msg.sender == _registrar); _; } modifier onlyActive { require(active); _; } constructor(address payable initialOwner) public payable { _owner = initialOwner; _registrar = msg.sender; _creationDate = now; active = true; _value = msg.value; } function setOwner(address payable newOwner) external onlyRegistrar { require(newOwner != address(0x0)); _previousOwner = _owner; // This allows contracts to check who sent them the ownership _owner = newOwner; emit OwnerChanged(newOwner); } function setRegistrar(address newRegistrar) external onlyRegistrar { _registrar = newRegistrar; } function setBalance(uint newValue, bool throwOnFailure) external onlyRegistrar onlyActive { // Check if it has enough balance to set the value require(_value >= newValue); _value = newValue; // Send the difference to the owner require(_owner.send(address(this).balance - newValue) || !throwOnFailure); } /** * @dev Close a deed and refund a specified fraction of the bid value * * @param refundRatio The amount*1/1000 to refund */ function closeDeed(uint refundRatio) external onlyRegistrar onlyActive { active = false; require(burn.send(((1000 - refundRatio) * address(this).balance)/1000)); emit DeedClosed(); _destroyDeed(); } /** * @dev Close a deed and refund a specified fraction of the bid value */ function destroyDeed() external { _destroyDeed(); } function owner() external view returns (address) { return _owner; } function previousOwner() external view returns (address) { return _previousOwner; } function value() external view returns (uint) { return _value; } function creationDate() external view returns (uint) { _creationDate; } function _destroyDeed() internal { require(!active); // Instead of selfdestruct(owner), invoke owner fallback function to allow // owner to log an event if desired; but owner should also be aware that // its fallback function can also be invoked by setBalance if (_owner.send(address(this).balance)) { selfdestruct(burn); } } } // File: @ensdomains/ens/contracts/HashRegistrar.sol pragma solidity ^0.5.0; /* Temporary Hash Registrar ======================== This is a simplified version of a hash registrar. It is purporsefully limited: names cannot be six letters or shorter, new auctions will stop after 4 years. The plan is to test the basic features and then move to a new contract in at most 2 years, when some sort of renewal mechanism will be enabled. */ /** * @title Registrar * @dev The registrar handles the auction process for each subnode of the node it owns. */ contract HashRegistrar is Registrar { ENS public ens; bytes32 public rootNode; mapping (bytes32 => Entry) _entries; mapping (address => mapping (bytes32 => Deed)) public sealedBids; uint32 constant totalAuctionLength = 5 days; uint32 constant revealPeriod = 48 hours; uint32 public constant launchLength = 8 weeks; uint constant minPrice = 0.01 ether; uint public registryStarted; struct Entry { Deed deed; uint registrationDate; uint value; uint highestBid; } modifier inState(bytes32 _hash, Mode _state) { require(state(_hash) == _state); _; } modifier onlyOwner(bytes32 _hash) { require(state(_hash) == Mode.Owned && msg.sender == _entries[_hash].deed.owner()); _; } modifier registryOpen() { require(now >= registryStarted && now <= registryStarted + (365 * 4) * 1 days && ens.owner(rootNode) == address(this)); _; } /** * @dev Constructs a new Registrar, with the provided address as the owner of the root node. * * @param _ens The address of the ENS * @param _rootNode The hash of the rootnode. */ constructor(ENS _ens, bytes32 _rootNode, uint _startDate) public { ens = _ens; rootNode = _rootNode; registryStarted = _startDate > 0 ? _startDate : now; } /** * @dev Start an auction for an available hash * * @param _hash The hash to start an auction on */ function startAuction(bytes32 _hash) external { _startAuction(_hash); } /** * @dev Start multiple auctions for better anonymity * * Anyone can start an auction by sending an array of hashes that they want to bid for. * Arrays are sent so that someone can open up an auction for X dummy hashes when they * are only really interested in bidding for one. This will increase the cost for an * attacker to simply bid blindly on all new auctions. Dummy auctions that are * open but not bid on are closed after a week. * * @param _hashes An array of hashes, at least one of which you presumably want to bid on */ function startAuctions(bytes32[] calldata _hashes) external { _startAuctions(_hashes); } /** * @dev Submit a new sealed bid on a desired hash in a blind auction * * Bids are sent by sending a message to the main contract with a hash and an amount. The hash * contains information about the bid, including the bidded hash, the bid amount, and a random * salt. Bids are not tied to any one auction until they are revealed. The value of the bid * itself can be masqueraded by sending more than the value of your actual bid. This is * followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. * Since this is an auction, it is expected that most public hashes, like known domains and common dictionary * words, will have multiple bidders pushing the price up. * * @param sealedBid A sealedBid, created by the shaBid function */ function newBid(bytes32 sealedBid) external payable { _newBid(sealedBid); } /** * @dev Start a set of auctions and bid on one of them * * This method functions identically to calling `startAuctions` followed by `newBid`, * but all in one transaction. * * @param hashes A list of hashes to start auctions on. * @param sealedBid A sealed bid for one of the auctions. */ function startAuctionsAndBid(bytes32[] calldata hashes, bytes32 sealedBid) external payable { _startAuctions(hashes); _newBid(sealedBid); } /** * @dev Submit the properties of a bid to reveal them * * @param _hash The node in the sealedBid * @param _value The bid amount in the sealedBid * @param _salt The sale in the sealedBid */ function unsealBid(bytes32 _hash, uint _value, bytes32 _salt) external { bytes32 seal = shaBid(_hash, msg.sender, _value, _salt); Deed bid = sealedBids[msg.sender][seal]; require(address(bid) != address(0x0)); sealedBids[msg.sender][seal] = Deed(address(0x0)); Entry storage h = _entries[_hash]; uint value = min(_value, bid.value()); bid.setBalance(value, true); Mode auctionState = state(_hash); if (auctionState == Mode.Owned) { // Too late! Bidder loses their bid. Gets 0.5% back. bid.closeDeed(5); emit BidRevealed(_hash, msg.sender, value, 1); } else if (auctionState != Mode.Reveal) { // Invalid phase revert(); } else if (value < minPrice || bid.creationDate() > h.registrationDate - revealPeriod) { // Bid too low or too late, refund 99.5% bid.closeDeed(995); emit BidRevealed(_hash, msg.sender, value, 0); } else if (value > h.highestBid) { // New winner // Cancel the other bid, refund 99.5% if (address(h.deed) != address(0x0)) { Deed previousWinner = h.deed; previousWinner.closeDeed(995); } // Set new winner // Per the rules of a vickery auction, the value becomes the previous highestBid h.value = h.highestBid; // will be zero if there's only 1 bidder h.highestBid = value; h.deed = bid; emit BidRevealed(_hash, msg.sender, value, 2); } else if (value > h.value) { // Not winner, but affects second place h.value = value; bid.closeDeed(995); emit BidRevealed(_hash, msg.sender, value, 3); } else { // Bid doesn't affect auction bid.closeDeed(995); emit BidRevealed(_hash, msg.sender, value, 4); } } /** * @dev Cancel a bid * * @param seal The value returned by the shaBid function */ function cancelBid(address bidder, bytes32 seal) external { Deed bid = sealedBids[bidder][seal]; // If a sole bidder does not `unsealBid` in time, they have a few more days // where they can call `startAuction` (again) and then `unsealBid` during // the revealPeriod to get back their bid value. // For simplicity, they should call `startAuction` within // 9 days (2 weeks - totalAuctionLength), otherwise their bid will be // cancellable by anyone. require(address(bid) != address(0x0) && now >= bid.creationDate() + totalAuctionLength + 2 weeks); // Send the canceller 0.5% of the bid, and burn the rest. bid.setOwner(msg.sender); bid.closeDeed(5); sealedBids[bidder][seal] = Deed(0); emit BidRevealed(seal, bidder, 0, 5); } /** * @dev Finalize an auction after the registration date has passed * * @param _hash The hash of the name the auction is for */ function finalizeAuction(bytes32 _hash) external onlyOwner(_hash) { Entry storage h = _entries[_hash]; // Handles the case when there's only a single bidder (h.value is zero) h.value = max(h.value, minPrice); h.deed.setBalance(h.value, true); trySetSubnodeOwner(_hash, h.deed.owner()); emit HashRegistered(_hash, h.deed.owner(), h.value, h.registrationDate); } /** * @dev The owner of a domain may transfer it to someone else at any time. * * @param _hash The node to transfer * @param newOwner The address to transfer ownership to */ function transfer(bytes32 _hash, address payable newOwner) external onlyOwner(_hash) { require(newOwner != address(0x0)); Entry storage h = _entries[_hash]; h.deed.setOwner(newOwner); trySetSubnodeOwner(_hash, newOwner); } /** * @dev After some time, or if we're no longer the registrar, the owner can release * the name and get their ether back. * * @param _hash The node to release */ function releaseDeed(bytes32 _hash) external onlyOwner(_hash) { Entry storage h = _entries[_hash]; Deed deedContract = h.deed; require(now >= h.registrationDate + 365 days || ens.owner(rootNode) != address(this)); h.value = 0; h.highestBid = 0; h.deed = Deed(0); _tryEraseSingleNode(_hash); deedContract.closeDeed(1000); emit HashReleased(_hash, h.value); } /** * @dev Submit a name 6 characters long or less. If it has been registered, * the submitter will earn 50% of the deed value. * * We are purposefully handicapping the simplified registrar as a way * to force it into being restructured in a few years. * * @param unhashedName An invalid name to search for in the registry. */ function invalidateName(string calldata unhashedName) external inState(keccak256(abi.encode(unhashedName)), Mode.Owned) { require(strlen(unhashedName) <= 6); bytes32 hash = keccak256(abi.encode(unhashedName)); Entry storage h = _entries[hash]; _tryEraseSingleNode(hash); if (address(h.deed) != address(0x0)) { // Reward the discoverer with 50% of the deed // The previous owner gets 50% h.value = max(h.value, minPrice); h.deed.setBalance(h.value/2, false); h.deed.setOwner(msg.sender); h.deed.closeDeed(1000); } emit HashInvalidated(hash, unhashedName, h.value, h.registrationDate); h.value = 0; h.highestBid = 0; h.deed = Deed(0); } /** * @dev Allows anyone to delete the owner and resolver records for a (subdomain of) a * name that is not currently owned in the registrar. If passing, eg, 'foo.bar.eth', * the owner and resolver fields on 'foo.bar.eth' and 'bar.eth' will all be cleared. * * @param labels A series of label hashes identifying the name to zero out, rooted at the * registrar's root. Must contain at least one element. For instance, to zero * 'foo.bar.eth' on a registrar that owns '.eth', pass an array containing * [keccak256('foo'), keccak256('bar')]. */ function eraseNode(bytes32[] calldata labels) external { require(labels.length != 0); require(state(labels[labels.length - 1]) != Mode.Owned); _eraseNodeHierarchy(labels.length - 1, labels, rootNode); } /** * @dev Transfers the deed to the current registrar, if different from this one. * * Used during the upgrade process to a permanent registrar. * * @param _hash The name hash to transfer. */ function transferRegistrars(bytes32 _hash) external onlyOwner(_hash) { address registrar = ens.owner(rootNode); require(registrar != address(this)); // Migrate the deed Entry storage h = _entries[_hash]; h.deed.setRegistrar(registrar); // Call the new registrar to accept the transfer Registrar(registrar).acceptRegistrarTransfer(_hash, h.deed, h.registrationDate); // Zero out the Entry h.deed = Deed(0); h.registrationDate = 0; h.value = 0; h.highestBid = 0; } /** * @dev Accepts a transfer from a previous registrar; stubbed out here since there * is no previous registrar implementing this interface. * * @param hash The sha3 hash of the label to transfer. * @param deed The Deed object for the name being transferred in. * @param registrationDate The date at which the name was originally registered. */ function acceptRegistrarTransfer(bytes32 hash, Deed deed, uint registrationDate) external { hash; deed; registrationDate; // Don't warn about unused variables } function entries(bytes32 _hash) external view returns (Mode, address, uint, uint, uint) { Entry storage h = _entries[_hash]; return (state(_hash), address(h.deed), h.registrationDate, h.value, h.highestBid); } // State transitions for names: // Open -> Auction (startAuction) // Auction -> Reveal // Reveal -> Owned // Reveal -> Open (if nobody bid) // Owned -> Open (releaseDeed or invalidateName) function state(bytes32 _hash) public view returns (Mode) { Entry storage entry = _entries[_hash]; if (!isAllowed(_hash, now)) { return Mode.NotYetAvailable; } else if (now < entry.registrationDate) { if (now < entry.registrationDate - revealPeriod) { return Mode.Auction; } else { return Mode.Reveal; } } else { if (entry.highestBid == 0) { return Mode.Open; } else { return Mode.Owned; } } } /** * @dev Determines if a name is available for registration yet * * Each name will be assigned a random date in which its auction * can be started, from 0 to 8 weeks * * @param _hash The hash to start an auction on * @param _timestamp The timestamp to query about */ function isAllowed(bytes32 _hash, uint _timestamp) public view returns (bool allowed) { return _timestamp > getAllowedTime(_hash); } /** * @dev Returns available date for hash * * The available time from the `registryStarted` for a hash is proportional * to its numeric value. * * @param _hash The hash to start an auction on */ function getAllowedTime(bytes32 _hash) public view returns (uint) { return registryStarted + ((launchLength * (uint(_hash) >> 128)) >> 128); // Right shift operator: a >> b == a / 2**b } /** * @dev Hash the values required for a secret bid * * @param hash The node corresponding to the desired namehash * @param value The bid amount * @param salt A random value to ensure secrecy of the bid * @return The hash of the bid values */ function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) public pure returns (bytes32) { return keccak256(abi.encodePacked(hash, owner, value, salt)); } function _tryEraseSingleNode(bytes32 label) internal { if (ens.owner(rootNode) == address(this)) { ens.setSubnodeOwner(rootNode, label, address(this)); bytes32 node = keccak256(abi.encodePacked(rootNode, label)); ens.setResolver(node, address(0x0)); ens.setOwner(node, address(0x0)); } } function _startAuction(bytes32 _hash) internal registryOpen() { Mode mode = state(_hash); if (mode == Mode.Auction) return; require(mode == Mode.Open); Entry storage newAuction = _entries[_hash]; newAuction.registrationDate = now + totalAuctionLength; newAuction.value = 0; newAuction.highestBid = 0; emit AuctionStarted(_hash, newAuction.registrationDate); } function _startAuctions(bytes32[] memory _hashes) internal { for (uint i = 0; i < _hashes.length; i ++) { _startAuction(_hashes[i]); } } function _newBid(bytes32 sealedBid) internal { require(address(sealedBids[msg.sender][sealedBid]) == address(0x0)); require(msg.value >= minPrice); // Creates a new hash contract with the owner Deed bid = (new DeedImplementation).value(msg.value)(msg.sender); sealedBids[msg.sender][sealedBid] = bid; emit NewBid(sealedBid, msg.sender, msg.value); } function _eraseNodeHierarchy(uint idx, bytes32[] memory labels, bytes32 node) internal { // Take ownership of the node ens.setSubnodeOwner(node, labels[idx], address(this)); node = keccak256(abi.encodePacked(node, labels[idx])); // Recurse if there are more labels if (idx > 0) { _eraseNodeHierarchy(idx - 1, labels, node); } // Erase the resolver and owner records ens.setResolver(node, address(0x0)); ens.setOwner(node, address(0x0)); } /** * @dev Assign the owner in ENS, if we're still the registrar * * @param _hash hash to change owner * @param _newOwner new owner to transfer to */ function trySetSubnodeOwner(bytes32 _hash, address _newOwner) internal { if (ens.owner(rootNode) == address(this)) ens.setSubnodeOwner(rootNode, _hash, _newOwner); } /** * @dev Returns the maximum of two unsigned integers * * @param a A number to compare * @param b A number to compare * @return The maximum of two unsigned integers */ function max(uint a, uint b) internal pure returns (uint) { if (a > b) return a; else return b; } /** * @dev Returns the minimum of two unsigned integers * * @param a A number to compare * @param b A number to compare * @return The minimum of two unsigned integers */ function min(uint a, uint b) internal pure returns (uint) { if (a < b) return a; else return b; } /** * @dev Returns the length of a given string * * @param s The string to measure the length of * @return The length of the input string */ function strlen(string memory s) internal pure returns (uint) { s; // Don't warn about unused variables // Starting here means the LSB will be the byte we care about uint ptr; uint end; assembly { ptr := add(s, 1) end := add(mload(s), ptr) } uint len = 0; for (len; ptr < end; len++) { uint8 b; assembly { b := and(mload(ptr), 0xFF) } if (b < 0x80) { ptr += 1; } else if (b < 0xE0) { ptr += 2; } else if (b < 0xF0) { ptr += 3; } else if (b < 0xF8) { ptr += 4; } else if (b < 0xFC) { ptr += 5; } else { ptr += 6; } } return len; } } // File: @ensdomains/ethregistrar/contracts/OldBaseRegistrarImplementation.sol pragma solidity ^0.5.0; contract OldBaseRegistrarImplementation is BaseRegistrar, ERC721 { // Expiration timestamp for migrated domains. uint public transferPeriodEnds; // The interim registrar Registrar public previousRegistrar; // A map of expiry times mapping(uint256=>uint) expiries; uint constant public MIGRATION_LOCK_PERIOD = 28 days; bytes4 constant private INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)")); bytes4 constant private ERC721_ID = bytes4( keccak256("balanceOf(uint256)") ^ keccak256("ownerOf(uint256)") ^ keccak256("approve(address,uint256)") ^ keccak256("getApproved(uint256)") ^ keccak256("setApprovalForAll(address,bool)") ^ keccak256("isApprovedForAll(address,address)") ^ keccak256("transferFrom(address,address,uint256)") ^ keccak256("safeTransferFrom(address,address,uint256)") ^ keccak256("safeTransferFrom(address,address,uint256,bytes)") ); bytes4 constant private RECLAIM_ID = bytes4(keccak256("reclaim(uint256,address)")); constructor(ENS _ens, HashRegistrar _previousRegistrar, bytes32 _baseNode, uint _transferPeriodEnds) public { // Require that people have time to transfer names over. require(_transferPeriodEnds > now + 2 * MIGRATION_LOCK_PERIOD); ens = _ens; baseNode = _baseNode; previousRegistrar = _previousRegistrar; transferPeriodEnds = _transferPeriodEnds; } modifier live { require(ens.owner(baseNode) == address(this)); _; } modifier onlyController { require(controllers[msg.sender]); _; } /** * @dev Gets the owner of the specified token ID. Names become unowned * when their registration expires. * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { require(expiries[tokenId] > now); return super.ownerOf(tokenId); } // Authorises a controller, who can register and renew domains. function addController(address controller) external onlyOwner { controllers[controller] = true; emit ControllerAdded(controller); } // Revoke controller permission for an address. function removeController(address controller) external onlyOwner { controllers[controller] = false; emit ControllerRemoved(controller); } // Set the resolver for the TLD this registrar manages. function setResolver(address resolver) external onlyOwner { ens.setResolver(baseNode, resolver); } // Returns the expiration timestamp of the specified id. function nameExpires(uint256 id) external view returns(uint) { return expiries[id]; } // Returns true iff the specified name is available for registration. function available(uint256 id) public view returns(bool) { // Not available if it's registered here or in its grace period. if(expiries[id] + GRACE_PERIOD >= now) { return false; } // Available if we're past the transfer period, or the name isn't // registered in the legacy registrar. return now > transferPeriodEnds || previousRegistrar.state(bytes32(id)) == Registrar.Mode.Open; } /** * @dev Register a name. */ function register(uint256 id, address owner, uint duration) external returns(uint) { return _register(id, owner, duration, true); } /** * @dev Register a name. */ function registerOnly(uint256 id, address owner, uint duration) external returns(uint) { return _register(id, owner, duration, false); } /** * @dev Register a name. */ function _register(uint256 id, address owner, uint duration, bool updateRegistry) internal live onlyController returns(uint) { require(available(id)); require(now + duration + GRACE_PERIOD > now + GRACE_PERIOD); // Prevent future overflow expiries[id] = now + duration; if(_exists(id)) { // Name was previously owned, and expired _burn(id); } _mint(owner, id); if(updateRegistry) { ens.setSubnodeOwner(baseNode, bytes32(id), owner); } emit NameRegistered(id, owner, now + duration); return now + duration; } function renew(uint256 id, uint duration) external live onlyController returns(uint) { require(expiries[id] + GRACE_PERIOD >= now); // Name must be registered here or in grace period require(expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD); // Prevent future overflow expiries[id] += duration; emit NameRenewed(id, expiries[id]); return expiries[id]; } /** * @dev Reclaim ownership of a name in ENS, if you own it in the registrar. */ function reclaim(uint256 id, address owner) external live { require(_isApprovedOrOwner(msg.sender, id)); ens.setSubnodeOwner(baseNode, bytes32(id), owner); } /** * @dev Transfers a registration from the initial registrar. * This function is called by the initial registrar when a user calls `transferRegistrars`. */ function acceptRegistrarTransfer(bytes32 label, Deed deed, uint) external live { uint256 id = uint256(label); require(msg.sender == address(previousRegistrar)); require(expiries[id] == 0); require(transferPeriodEnds > now); uint registrationDate; (,,registrationDate,,) = previousRegistrar.entries(label); require(registrationDate < now - MIGRATION_LOCK_PERIOD); address owner = deed.owner(); // Destroy the deed and transfer the funds back to the registrant. deed.closeDeed(1000); // Register the name expiries[id] = transferPeriodEnds; _mint(owner, id); ens.setSubnodeOwner(baseNode, label, owner); emit NameMigrated(id, owner, transferPeriodEnds); emit NameRegistered(id, owner, transferPeriodEnds); } function supportsInterface(bytes4 interfaceID) external view returns (bool) { return interfaceID == INTERFACE_META_ID || interfaceID == ERC721_ID || interfaceID == RECLAIM_ID; } } // File: @ensdomains/ethregistrar/contracts/RegistrarMigration.sol pragma solidity ^0.5.0; contract RegistrarMigration { using SafeMath for uint; bytes constant private UNUSED_SUBDOMAIN = hex'ffffffffffffffff'; Registrar public legacyRegistrar; uint transferPeriodEnds; OldBaseRegistrarImplementation public oldRegistrar; BaseRegistrarImplementation public newRegistrar; ENS public oldENS; ENS public newENS; AbstractSubdomainRegistrar public oldSubdomainRegistrar; AbstractSubdomainRegistrar public newSubdomainRegistrar; bytes32 public baseNode; constructor(OldBaseRegistrarImplementation _old, BaseRegistrarImplementation _new, AbstractSubdomainRegistrar _oldSubdomainRegistrar, AbstractSubdomainRegistrar _newSubdomainRegistrar) public { oldRegistrar = _old; oldENS = _old.ens(); baseNode = _old.baseNode(); legacyRegistrar = _old.previousRegistrar(); transferPeriodEnds = _old.transferPeriodEnds(); oldSubdomainRegistrar = _oldSubdomainRegistrar; newRegistrar = _new; newENS = _new.ens(); require(_new.baseNode() == baseNode); newSubdomainRegistrar = _newSubdomainRegistrar; } function doMigration(uint256 tokenId, address registrant, uint expires) internal { bytes32 node = keccak256(abi.encodePacked(baseNode, bytes32(tokenId))); address controller = oldENS.owner(node); if(address(registrant) != address(oldSubdomainRegistrar) && hasCode(controller)) { // For names controlled by a contract or not in ENS, only migrate over the registration newRegistrar.registerOnly(tokenId, registrant, expires.sub(now)); return; } // Register the name on the new registry with the same expiry time. newRegistrar.register(tokenId, address(this), expires.sub(now)); // Copy over resolver, TTL and owner to the new registry. address resolver = oldENS.resolver(node); if(resolver != address(0)) { newENS.setResolver(node, resolver); } uint64 ttl = oldENS.ttl(node); if(ttl != 0) { newENS.setTTL(node, ttl); } if(address(registrant) == address(oldSubdomainRegistrar) && address(registrant) != address(0)) { // Handle subdomain registrar domains // Fetch data from the old subdomain registrar (string memory label, uint price,, uint referralFeePPM) = oldSubdomainRegistrar.query(bytes32(tokenId), string(UNUSED_SUBDOMAIN)); address owner = oldSubdomainRegistrar.owner(bytes32(tokenId)); if(bytes(label).length == 0) { revert("Unable to migrate domain on subdomain registrar"); } // Transfer to the new subdomain registrar newRegistrar.approve(address(newSubdomainRegistrar), tokenId); newSubdomainRegistrar.configureDomainFor(label, price, referralFeePPM, address(uint160(owner)), address(0)); } else { newENS.setOwner(node, controller); // Transfer the registration to the registrant. newRegistrar.transferFrom(address(this), registrant, tokenId); } // Replace ownership on the old registry so it can't be updated any further. oldENS.setSubnodeOwner(baseNode, bytes32(tokenId), address(this)); } /** * @dev Migrate a name from the previous version of the BaseRegistrar */ function migrate(uint256 tokenId) public { address registrant = oldRegistrar.ownerOf(tokenId); doMigration(tokenId, registrant, oldRegistrar.nameExpires(tokenId)); } /** * @dev Migrate a list of names from the previous version of the BaseRegistrar. */ function migrateAll(uint256[] calldata tokenIds) external { for(uint i = 0; i < tokenIds.length; i++) { migrate(tokenIds[i]); } } /** * @dev Migrate a name from the legacy (auction-based) registrar. */ function migrateLegacy(bytes32 label) public { (Registrar.Mode mode, address deed, , ,) = legacyRegistrar.entries(label); require(mode == Registrar.Mode.Owned); address owner = Deed(deed).owner(); doMigration(uint256(label), owner, transferPeriodEnds); } /** * @dev Migrate a list of names from the legacy (auction-based) registrar. */ function migrateAllLegacy(bytes32[] calldata labels) external { for(uint i = 0; i < labels.length; i++) { migrateLegacy(labels[i]); } } function hasCode(address addr) private view returns(bool ret) { assembly { ret := not(not(extcodesize(addr))) } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract OldBaseRegistrarImplementation","name":"_old","type":"address"},{"internalType":"contract BaseRegistrarImplementation","name":"_new","type":"address"},{"internalType":"contract AbstractSubdomainRegistrar","name":"_oldSubdomainRegistrar","type":"address"},{"internalType":"contract AbstractSubdomainRegistrar","name":"_newSubdomainRegistrar","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"baseNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"legacyRegistrar","outputs":[{"internalType":"contract Registrar","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"migrate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"migrateAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"labels","type":"bytes32[]"}],"name":"migrateAllLegacy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"label","type":"bytes32"}],"name":"migrateLegacy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newENS","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newRegistrar","outputs":[{"internalType":"contract BaseRegistrarImplementation","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newSubdomainRegistrar","outputs":[{"internalType":"contract AbstractSubdomainRegistrar","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oldENS","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oldRegistrar","outputs":[{"internalType":"contract OldBaseRegistrarImplementation","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oldSubdomainRegistrar","outputs":[{"internalType":"contract AbstractSubdomainRegistrar","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162001e1538038062001e15833981810160405260808110156200003757600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505083600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16633f15457f6040518163ffffffff1660e01b815260040160206040518083038186803b158015620000ee57600080fd5b505afa15801562000103573d6000803e3d6000fd5b505050506040513d60208110156200011a57600080fd5b8101908080519060200190929190505050600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff1663ddf7fcb06040518163ffffffff1660e01b815260040160206040518083038186803b158015620001b257600080fd5b505afa158015620001c7573d6000803e3d6000fd5b505050506040513d6020811015620001de57600080fd5b81019080805190602001909291905050506008819055508373ffffffffffffffffffffffffffffffffffffffff1663ab14ec596040518163ffffffff1660e01b815260040160206040518083038186803b1580156200023c57600080fd5b505afa15801562000251573d6000803e3d6000fd5b505050506040513d60208110156200026857600080fd5b81019080805190602001909291905050506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16634ae05da76040518163ffffffff1660e01b815260040160206040518083038186803b158015620002ff57600080fd5b505afa15801562000314573d6000803e3d6000fd5b505050506040513d60208110156200032b57600080fd5b810190808051906020019092919050505060018190555081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff16633f15457f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200040b57600080fd5b505afa15801562000420573d6000803e3d6000fd5b505050506040513d60208110156200043757600080fd5b8101908080519060200190929190505050600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506008548373ffffffffffffffffffffffffffffffffffffffff1663ddf7fcb06040518163ffffffff1660e01b815260040160206040518083038186803b158015620004d257600080fd5b505afa158015620004e7573d6000803e3d6000fd5b505050506040513d6020811015620004fe57600080fd5b8101908080519060200190929190505050146200051a57600080fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050506118a6806200056f6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80636a657777116100715780636a6577771461023d57806378635026146102875780638e7e879f146102d157806393a8dddb1461034a57806398df3cb214610394578063ddf7fcb01461040d576100b4565b8063156f54db146100b95780632610ad59146100e75780632d2f3f27146101315780633c9b51b41461017b57806341c5e244146101c5578063454b06081461020f575b600080fd5b6100e5600480360360208110156100cf57600080fd5b810190808035906020019092919050505061042b565b005b6100ef6105c8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101396105ee565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610183610614565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101cd61063a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61023b6004803603602081101561022557600080fd5b8101908080359060200190929190505050610660565b005b6102456107ce565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028f6107f3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610348600480360360208110156102e757600080fd5b810190808035906020019064010000000081111561030457600080fd5b82018360208201111561031657600080fd5b8035906020019184602083028401116401000000008311171561033857600080fd5b9091929391929390505050610819565b005b610352610857565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61040b600480360360208110156103aa57600080fd5b81019080803590602001906401000000008111156103c757600080fd5b8201836020820111156103d957600080fd5b803590602001918460208302840111640100000000831117156103fb57600080fd5b909192939192939050505061087d565b005b6104156108bb565b6040518082815260200191505060405180910390f35b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663267b6922846040518263ffffffff1660e01b81526004018082815260200191505060a06040518083038186803b1580156104a057600080fd5b505afa1580156104b4573d6000803e3d6000fd5b505050506040513d60a08110156104ca57600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050505050915091506002600581111561051757fe5b82600581111561052357fe5b1461052d57600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561057557600080fd5b505afa158015610589573d6000803e3d6000fd5b505050506040513d602081101561059f57600080fd5b810190808051906020019092919050505090506105c28460001c826001546108c1565b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156106d557600080fd5b505afa1580156106e9573d6000803e3d6000fd5b505050506040513d60208110156106ff57600080fd5b810190808051906020019092919050505090506107ca8282600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6e4fa86866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561078a57600080fd5b505afa15801561079e573d6000803e3d6000fd5b505050506040513d60208110156107b457600080fd5b81019080805190602001909291905050506108c1565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b828290508110156108525761084583838381811061083957fe5b90506020020135610660565b808060010191505061081f565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b828290508110156108b6576108a983838381811061089d57fe5b9050602002013561042b565b8080600101915050610883565b505050565b60085481565b60006008548460001b60405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561096e57600080fd5b505afa158015610982573d6000803e3d6000fd5b505050506040513d602081101561099857600080fd5b81019080805190602001909291905050509050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610a0e5750610a0d81611815565b5b15610b1957600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e297b458686610a66428861182290919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610ad657600080fd5b505af1158015610aea573d6000803e3d6000fd5b505050506040513d6020811015610b0057600080fd5b8101908080519060200190929190505050505050611810565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fca247ac8630610b6c428861182290919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d6020811015610c0657600080fd5b8101908080519060200190929190505050506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6020811015610cb757600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610dc057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a84836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166316a25cbd856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e3557600080fd5b505afa158015610e49573d6000803e3d6000fd5b505050506040513d6020811015610e5f57600080fd5b8101908080519060200190929190505050905060008167ffffffffffffffff1614610f2e57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166314ab903885836040518363ffffffff1660e01b8152600401808381526020018267ffffffffffffffff1667ffffffffffffffff16815260200192505050600060405180830381600087803b158015610f1557600080fd5b505af1158015610f29573d6000803e3d6000fd5b505050505b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148015610fb85750600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614155b15611562576060600080600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632eef3d658b60001b6040518060400160405280600881526020017fffffffffffffffff0000000000000000000000000000000000000000000000008152506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561108f578082015181840152602081019050611074565b50505050905090810190601f1680156110bc5780820380516001836020036101000a031916815260200191505b50935050505060006040518083038186803b1580156110da57600080fd5b505afa1580156110ee573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561111857600080fd5b810190808051604051939291908464010000000082111561113857600080fd5b8382019150602082018581111561114e57600080fd5b825186600182028301116401000000008211171561116b57600080fd5b8083526020830192505050908051906020019080838360005b8381101561119f578082015181840152602081019050611184565b50505050905090810190601f1680156111cc5780820380516001836020036101000a031916815260200191505b50604052602001805190602001909291908051906020019092919080519060200190929190505050935050925092506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be38c60001b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561127357600080fd5b505afa158015611287573d6000803e3d6000fd5b505050506040513d602081101561129d57600080fd5b8101908080519060200190929190505050905060008451141561130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180611843602f913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156113d657600080fd5b505af11580156113ea573d6000803e3d6000fd5b50505050600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf7752558585858560006040518663ffffffff1660e01b815260040180806020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b838110156114f15780820151818401526020810190506114d6565b50505050905090810190601f16801561151e5780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561154157600080fd5b505af1158015611555573d6000803e3d6000fd5b5050505050505050611719565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c385856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561160b57600080fd5b505af115801561161f573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd30888a6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561170057600080fd5b505af1158015611714573d6000803e3d6000fd5b505050505b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59236008548960001b306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050602060405180830381600087803b1580156117cf57600080fd5b505af11580156117e3573d6000803e3d6000fd5b505050506040513d60208110156117f957600080fd5b810190808051906020019092919050505050505050505b505050565b6000813b19199050919050565b60008282111561183157600080fd5b60008284039050809150509291505056fe556e61626c6520746f206d69677261746520646f6d61696e206f6e20737562646f6d61696e20726567697374726172a265627a7a723158209a35bf408d98883bf177340388ace32f17d2274afeca6cbce04d027adf3f650d64736f6c63430005100032000000000000000000000000fac7bea255a6990f749363002136af6556b31e0400000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85000000000000000000000000c32659651d137a18b79925449722855aa327231d000000000000000000000000e65d8aaf34cb91087d1598e0a15b582f57f217d9
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fac7bea255a6990f749363002136af6556b31e0400000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85000000000000000000000000c32659651d137a18b79925449722855aa327231d000000000000000000000000e65d8aaf34cb91087d1598e0a15b582f57f217d9
-----Decoded View---------------
Arg [0] : _old (address): 0xFaC7BEA255a6990f749363002136aF6556b31e04
Arg [1] : _new (address): 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
Arg [2] : _oldSubdomainRegistrar (address): 0xC32659651D137A18b79925449722855aA327231d
Arg [3] : _newSubdomainRegistrar (address): 0xe65d8AAF34CB91087D1598e0A15B582F57F217d9
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000fac7bea255a6990f749363002136af6556b31e04
Arg [1] : 00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85
Arg [2] : 000000000000000000000000c32659651d137a18b79925449722855aa327231d
Arg [3] : 000000000000000000000000e65d8aaf34cb91087d1598e0a15b582f57f217d9
Deployed ByteCode Sourcemap
67954:4778:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67954:4778:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72000:295;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72000:295:0;;;;;;;;;;;;;;;;;:::i;:::-;;68297:17;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68162:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68219:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68321:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;71439:188;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71439:188:0;;;;;;;;;;;;;;;;;:::i;:::-;;68093:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68383:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;71738:165;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71738:165:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;71738:165:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;71738:165:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;71738:165:0;;;;;;;;;;;;:::i;:::-;;68273:17;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;72401:171;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72401:171:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;72401:171:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72401:171:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;72401:171:0;;;;;;;;;;;;:::i;:::-;;68447:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;72000:295;72057:19;72078:12;72099:15;;;;;;;;;;;:23;;;72123:5;72099:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72099:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72099:30:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;72099:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72056:73;;;;;;;72156:20;72148:28;;;;;;;;:4;:28;;;;;;;;;72140:37;;;;;;72188:13;72209:4;72204:16;;;:18;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72204:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72204:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72204:18:0;;;;;;;;;;;;;;;;72188:34;;72233:54;72253:5;72245:14;;72261:5;72268:18;;72233:11;:54::i;:::-;72000:295;;;;:::o;68297:17::-;;;;;;;;;;;;;:::o;68162:50::-;;;;;;;;;;;;;:::o;68219:47::-;;;;;;;;;;;;;:::o;68321:55::-;;;;;;;;;;;;;:::o;71439:188::-;71491:18;71512:12;;;;;;;;;;;:20;;;71533:7;71512:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71512:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71512:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71512:29:0;;;;;;;;;;;;;;;;71491:50;;71552:67;71564:7;71573:10;71585:12;;;;;;;;;;;:24;;;71610:7;71585:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71585:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71585:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71585:33:0;;;;;;;;;;;;;;;;71552:11;:67::i;:::-;71439:188;;:::o;68093:32::-;;;;;;;;;;;;;:::o;68383:55::-;;;;;;;;;;;;;:::o;71738:165::-;71811:6;71820:1;71811:10;;71807:89;71827:8;;:15;;71823:1;:19;71807:89;;;71864:20;71872:8;;71881:1;71872:11;;;;;;;;;;;;;71864:7;:20::i;:::-;71844:3;;;;;;;71807:89;;;;71738:165;;:::o;68273:17::-;;;;;;;;;;;;;:::o;72401:171::-;72478:6;72487:1;72478:10;;72474:91;72494:6;;:13;;72490:1;:17;72474:91;;;72529:24;72543:6;;72550:1;72543:9;;;;;;;;;;;;;72529:13;:24::i;:::-;72509:3;;;;;;;72474:91;;;;72401:171;;:::o;68447:23::-;;;;:::o;69117:2221::-;69209:12;69251:8;;69269:7;69261:16;;69234:44;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;69234:44:0;;;69224:55;;;;;;69209:70;;69290:18;69311:6;;;;;;;;;;;:12;;;69324:4;69311:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69311:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69311:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;69311:18:0;;;;;;;;;;;;;;;;69290:39;;69376:21;;;;;;;;;;;69345:53;;69353:10;69345:53;;;;:76;;;;;69402:19;69410:10;69402:7;:19::i;:::-;69345:76;69342:294;;;69539:12;;;;;;;;;;;:25;;;69565:7;69574:10;69586:16;69598:3;69586:7;:11;;:16;;;;:::i;:::-;69539:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69539:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69539:64:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;69539:64:0;;;;;;;;;;;;;;;;;69618:7;;;;69342:294;69725:12;;;;;;;;;;;:21;;;69747:7;69764:4;69771:16;69783:3;69771:7;:11;;:16;;;;:::i;:::-;69725:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69725:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69725:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;69725:63:0;;;;;;;;;;;;;;;;;69868:16;69887:6;;;;;;;;;;;:15;;;69903:4;69887:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69887:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69887:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;69887:21:0;;;;;;;;;;;;;;;;69868:40;;69942:1;69922:22;;:8;:22;;;69919:88;;69961:6;;;;;;;;;;;:18;;;69980:4;69986:8;69961:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69961:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69961:34:0;;;;69919:88;70019:10;70032:6;;;;;;;;;;;:10;;;70043:4;70032:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70032:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70032:16:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;70032:16:0;;;;;;;;;;;;;;;;70019:29;;70069:1;70062:3;:8;;;70059:64;;70087:6;;;;;;;;;;;:13;;;70101:4;70107:3;70087:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70087:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70087:24:0;;;;70059:64;70169:21;;;;;;;;;;;70138:53;;70146:10;70138:53;;;:90;;;;;70226:1;70195:33;;70203:10;70195:33;;;;70138:90;70135:1032;;;70357:19;70378:10;70391:19;70414:21;;;;;;;;;;;:27;;;70450:7;70442:16;;70467;;;;;;;;;;;;;;;;;70414:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;70414:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70414:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70414:71:0;;;;;;39:16:-1;36:1;17:17;2:54;70414:71:0;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;13:3;8;5:12;2:2;;;30:1;27;20:12;2:2;70414:71:0;;;;;;;;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;71:11;66:3;62:21;55:28;;123:4;118:3;114:14;159:9;141:16;138:31;135:2;;;182:1;179;172:12;135:2;219:3;213:10;330:9;325:1;311:12;307:20;289:16;285:43;282:58;261:11;247:12;244:29;233:115;230:2;;;361:1;358;351:12;230:2;384:12;379:3;372:25;420:4;415:3;411:14;404:21;;0:432;;70414:71:0;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;70414:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70356:129;;;;;;;70500:13;70516:21;;;;;;;;;;;:27;;;70552:7;70544:16;;70516:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70516:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70516:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;70516:45:0;;;;;;;;;;;;;;;;70500:61;;70602:1;70585:5;70579:19;:24;70576:119;;;70622:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70576:119;70767:12;;;;;;;;;;;:20;;;70796:21;;;;;;;;;;;70820:7;70767:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70767:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70767:61:0;;;;70843:21;;;;;;;;;;;:40;;;70884:5;70891;70898:14;70930:5;70947:1;70843:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;70843:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70843:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70843:107:0;;;;70135:1032;;;;;;;70983:6;;;;;;;;;;;:15;;;70999:4;71005:10;70983:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70983:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70983:33:0;;;;71094:12;;;;;;;;;;;:25;;;71128:4;71135:10;71147:7;71094:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71094:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71094:61:0;;;;70135:1032;71265:6;;;;;;;;;;;:22;;;71288:8;;71306:7;71298:16;;71324:4;71265:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71265:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71265:65:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71265:65:0;;;;;;;;;;;;;;;;;69117:2221;;;;;;;;:::o;72580:149::-;72632:8;72704:4;72692:17;72688:22;72684:27;72677:34;;72662:60;;;:::o;14430:150::-;14488:7;14521:1;14516;:6;;14508:15;;;;;;14534:9;14550:1;14546;:5;14534:17;;14571:1;14564:8;;;14430:150;;;;:::o
Swarm Source
bzzr://9a35bf408d98883bf177340388ace32f17d2274afeca6cbce04d027adf3f650d
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.