More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 34,794 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Migrate All Lega... | 21088885 | 44 days ago | IN | 0 ETH | 0.00048192 | ||||
Migrate | 13697601 | 1113 days ago | IN | 0 ETH | 0.00469777 | ||||
Migrate | 13379706 | 1163 days ago | IN | 0 ETH | 0.00556919 | ||||
Migrate | 9894520 | 1702 days ago | IN | 0 ETH | 0.00005106 | ||||
Migrate All | 9893435 | 1702 days ago | IN | 0 ETH | 0.00006147 | ||||
Migrate | 9893261 | 1702 days ago | IN | 0 ETH | 0.00005106 | ||||
Migrate All | 9439940 | 1772 days ago | IN | 0 ETH | 0.00063795 | ||||
Migrate All Lega... | 9439940 | 1772 days ago | IN | 0 ETH | 0.00429129 | ||||
Migrate All Lega... | 9439404 | 1772 days ago | IN | 0 ETH | 0.00339203 | ||||
Migrate All | 9439404 | 1772 days ago | IN | 0 ETH | 0.00424489 | ||||
Migrate All Lega... | 9439404 | 1772 days ago | IN | 0 ETH | 0.00470843 | ||||
Migrate All Lega... | 9439404 | 1772 days ago | IN | 0 ETH | 0.00479993 | ||||
Migrate All | 9439404 | 1772 days ago | IN | 0 ETH | 0.00460166 | ||||
Migrate All Lega... | 9439402 | 1772 days ago | IN | 0 ETH | 0.00474208 | ||||
Migrate All Lega... | 9439402 | 1772 days ago | IN | 0 ETH | 0.00477879 | ||||
Migrate All | 9439401 | 1772 days ago | IN | 0 ETH | 0.00482974 | ||||
Migrate All Lega... | 9439401 | 1772 days ago | IN | 0 ETH | 0.00475465 | ||||
Migrate All | 9439401 | 1772 days ago | IN | 0 ETH | 0.00481714 | ||||
Migrate All Lega... | 9439400 | 1772 days ago | IN | 0 ETH | 0.00485765 | ||||
Migrate All | 9439400 | 1772 days ago | IN | 0 ETH | 0.0049863 | ||||
Migrate All Lega... | 9439400 | 1772 days ago | IN | 0 ETH | 0.00466326 | ||||
Migrate All Lega... | 9439400 | 1772 days ago | IN | 0 ETH | 0.00469578 | ||||
Migrate All Lega... | 9439393 | 1772 days ago | IN | 0 ETH | 0.00477457 | ||||
Migrate All | 9439391 | 1772 days ago | IN | 0 ETH | 0.00467206 | ||||
Migrate All Lega... | 9439391 | 1772 days ago | IN | 0 ETH | 0.00472107 |
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-02-03 */ // 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: 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: 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: 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: contracts/RegistrarMigration.sol pragma solidity ^0.5.0; pragma solidity >=0.4.24; interface OldENS { function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external; function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) 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); } contract RegistrarMigration { using SafeMath for uint; bytes constant private UNUSED_SUBDOMAIN = hex'ffffffffffffffff'; Registrar public legacyRegistrar; uint transferPeriodEnds; OldBaseRegistrarImplementation public oldRegistrar; BaseRegistrarImplementation public newRegistrar; OldENS 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 = OldENS(address(_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 OldENS","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
60806040523480156200001157600080fd5b5060405162001df138038062001df1833981810160405260808110156200003757600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505083600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16633f15457f6040518163ffffffff1660e01b815260040160206040518083038186803b158015620000ee57600080fd5b505afa15801562000103573d6000803e3d6000fd5b505050506040513d60208110156200011a57600080fd5b8101908080519060200190929190505050600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff1663ddf7fcb06040518163ffffffff1660e01b815260040160206040518083038186803b158015620001b257600080fd5b505afa158015620001c7573d6000803e3d6000fd5b505050506040513d6020811015620001de57600080fd5b81019080805190602001909291905050506008819055508373ffffffffffffffffffffffffffffffffffffffff1663ab14ec596040518163ffffffff1660e01b815260040160206040518083038186803b1580156200023c57600080fd5b505afa15801562000251573d6000803e3d6000fd5b505050506040513d60208110156200026857600080fd5b81019080805190602001909291905050506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16634ae05da76040518163ffffffff1660e01b815260040160206040518083038186803b158015620002ff57600080fd5b505afa15801562000314573d6000803e3d6000fd5b505050506040513d60208110156200032b57600080fd5b810190808051906020019092919050505060018190555081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff16633f15457f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200040b57600080fd5b505afa15801562000420573d6000803e3d6000fd5b505050506040513d60208110156200043757600080fd5b8101908080519060200190929190505050600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506008548373ffffffffffffffffffffffffffffffffffffffff1663ddf7fcb06040518163ffffffff1660e01b815260040160206040518083038186803b158015620004d257600080fd5b505afa158015620004e7573d6000803e3d6000fd5b505050506040513d6020811015620004fe57600080fd5b8101908080519060200190929190505050146200051a57600080fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050611882806200056f6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80636a657777116100715780636a6577771461023d57806378635026146102875780638e7e879f146102d157806393a8dddb1461034a57806398df3cb214610394578063ddf7fcb01461040d576100b4565b8063156f54db146100b95780632610ad59146100e75780632d2f3f27146101315780633c9b51b41461017b57806341c5e244146101c5578063454b06081461020f575b600080fd5b6100e5600480360360208110156100cf57600080fd5b810190808035906020019092919050505061042b565b005b6100ef6105c8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101396105ee565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610183610614565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101cd61063a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61023b6004803603602081101561022557600080fd5b8101908080359060200190929190505050610660565b005b6102456107ce565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028f6107f3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610348600480360360208110156102e757600080fd5b810190808035906020019064010000000081111561030457600080fd5b82018360208201111561031657600080fd5b8035906020019184602083028401116401000000008311171561033857600080fd5b9091929391929390505050610819565b005b610352610857565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61040b600480360360208110156103aa57600080fd5b81019080803590602001906401000000008111156103c757600080fd5b8201836020820111156103d957600080fd5b803590602001918460208302840111640100000000831117156103fb57600080fd5b909192939192939050505061087d565b005b6104156108bb565b6040518082815260200191505060405180910390f35b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663267b6922846040518263ffffffff1660e01b81526004018082815260200191505060a06040518083038186803b1580156104a057600080fd5b505afa1580156104b4573d6000803e3d6000fd5b505050506040513d60a08110156104ca57600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050505050915091506002600581111561051757fe5b82600581111561052357fe5b1461052d57600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561057557600080fd5b505afa158015610589573d6000803e3d6000fd5b505050506040513d602081101561059f57600080fd5b810190808051906020019092919050505090506105c28460001c826001546108c1565b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156106d557600080fd5b505afa1580156106e9573d6000803e3d6000fd5b505050506040513d60208110156106ff57600080fd5b810190808051906020019092919050505090506107ca8282600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6e4fa86866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561078a57600080fd5b505afa15801561079e573d6000803e3d6000fd5b505050506040513d60208110156107b457600080fd5b81019080805190602001909291905050506108c1565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b828290508110156108525761084583838381811061083957fe5b90506020020135610660565b808060010191505061081f565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b828290508110156108b6576108a983838381811061089d57fe5b9050602002013561042b565b8080600101915050610883565b505050565b60085481565b60006008548460001b60405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561096e57600080fd5b505afa158015610982573d6000803e3d6000fd5b505050506040513d602081101561099857600080fd5b81019080805190602001909291905050509050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610a0e5750610a0d816117f1565b5b15610b1957600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e297b458686610a6642886117fe90919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610ad657600080fd5b505af1158015610aea573d6000803e3d6000fd5b505050506040513d6020811015610b0057600080fd5b81019080805190602001909291905050505050506117ec565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fca247ac8630610b6c42886117fe90919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d6020811015610c0657600080fd5b8101908080519060200190929190505050506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6020811015610cb757600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610dc057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a84836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166316a25cbd856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e3557600080fd5b505afa158015610e49573d6000803e3d6000fd5b505050506040513d6020811015610e5f57600080fd5b8101908080519060200190929190505050905060008167ffffffffffffffff1614610f2e57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166314ab903885836040518363ffffffff1660e01b8152600401808381526020018267ffffffffffffffff1667ffffffffffffffff16815260200192505050600060405180830381600087803b158015610f1557600080fd5b505af1158015610f29573d6000803e3d6000fd5b505050505b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148015610fb85750600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614155b15611562576060600080600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632eef3d658b60001b6040518060400160405280600881526020017fffffffffffffffff0000000000000000000000000000000000000000000000008152506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561108f578082015181840152602081019050611074565b50505050905090810190601f1680156110bc5780820380516001836020036101000a031916815260200191505b50935050505060006040518083038186803b1580156110da57600080fd5b505afa1580156110ee573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561111857600080fd5b810190808051604051939291908464010000000082111561113857600080fd5b8382019150602082018581111561114e57600080fd5b825186600182028301116401000000008211171561116b57600080fd5b8083526020830192505050908051906020019080838360005b8381101561119f578082015181840152602081019050611184565b50505050905090810190601f1680156111cc5780820380516001836020036101000a031916815260200191505b50604052602001805190602001909291908051906020019092919080519060200190929190505050935050925092506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be38c60001b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561127357600080fd5b505afa158015611287573d6000803e3d6000fd5b505050506040513d602081101561129d57600080fd5b8101908080519060200190929190505050905060008451141561130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f81526020018061181f602f913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156113d657600080fd5b505af11580156113ea573d6000803e3d6000fd5b50505050600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf7752558585858560006040518663ffffffff1660e01b815260040180806020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b838110156114f15780820151818401526020810190506114d6565b50505050905090810190601f16801561151e5780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561154157600080fd5b505af1158015611555573d6000803e3d6000fd5b5050505050505050611719565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c385856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561160b57600080fd5b505af115801561161f573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd30888a6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561170057600080fd5b505af1158015611714573d6000803e3d6000fd5b505050505b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59236008548960001b306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b1580156117cf57600080fd5b505af11580156117e3573d6000803e3d6000fd5b50505050505050505b505050565b6000813b19199050919050565b60008282111561180d57600080fd5b60008284039050809150509291505056fe556e61626c6520746f206d69677261746520646f6d61696e206f6e20737562646f6d61696e20726567697374726172a265627a7a72315820b05e53db00a2a204eca6f3819046763a6beae4c3485927af38753d4c4001aaeb64736f6c63430005100032000000000000000000000000fac7bea255a6990f749363002136af6556b31e0400000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85000000000000000000000000c32659651d137a18b79925449722855aa327231d000000000000000000000000e65d8aaf34cb91087d1598e0a15b582f57f217d9
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80636a657777116100715780636a6577771461023d57806378635026146102875780638e7e879f146102d157806393a8dddb1461034a57806398df3cb214610394578063ddf7fcb01461040d576100b4565b8063156f54db146100b95780632610ad59146100e75780632d2f3f27146101315780633c9b51b41461017b57806341c5e244146101c5578063454b06081461020f575b600080fd5b6100e5600480360360208110156100cf57600080fd5b810190808035906020019092919050505061042b565b005b6100ef6105c8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101396105ee565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610183610614565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101cd61063a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61023b6004803603602081101561022557600080fd5b8101908080359060200190929190505050610660565b005b6102456107ce565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028f6107f3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610348600480360360208110156102e757600080fd5b810190808035906020019064010000000081111561030457600080fd5b82018360208201111561031657600080fd5b8035906020019184602083028401116401000000008311171561033857600080fd5b9091929391929390505050610819565b005b610352610857565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61040b600480360360208110156103aa57600080fd5b81019080803590602001906401000000008111156103c757600080fd5b8201836020820111156103d957600080fd5b803590602001918460208302840111640100000000831117156103fb57600080fd5b909192939192939050505061087d565b005b6104156108bb565b6040518082815260200191505060405180910390f35b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663267b6922846040518263ffffffff1660e01b81526004018082815260200191505060a06040518083038186803b1580156104a057600080fd5b505afa1580156104b4573d6000803e3d6000fd5b505050506040513d60a08110156104ca57600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050505050915091506002600581111561051757fe5b82600581111561052357fe5b1461052d57600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561057557600080fd5b505afa158015610589573d6000803e3d6000fd5b505050506040513d602081101561059f57600080fd5b810190808051906020019092919050505090506105c28460001c826001546108c1565b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156106d557600080fd5b505afa1580156106e9573d6000803e3d6000fd5b505050506040513d60208110156106ff57600080fd5b810190808051906020019092919050505090506107ca8282600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6e4fa86866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561078a57600080fd5b505afa15801561079e573d6000803e3d6000fd5b505050506040513d60208110156107b457600080fd5b81019080805190602001909291905050506108c1565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b828290508110156108525761084583838381811061083957fe5b90506020020135610660565b808060010191505061081f565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b828290508110156108b6576108a983838381811061089d57fe5b9050602002013561042b565b8080600101915050610883565b505050565b60085481565b60006008548460001b60405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561096e57600080fd5b505afa158015610982573d6000803e3d6000fd5b505050506040513d602081101561099857600080fd5b81019080805190602001909291905050509050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610a0e5750610a0d816117f1565b5b15610b1957600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e297b458686610a6642886117fe90919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610ad657600080fd5b505af1158015610aea573d6000803e3d6000fd5b505050506040513d6020811015610b0057600080fd5b81019080805190602001909291905050505050506117ec565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fca247ac8630610b6c42886117fe90919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d6020811015610c0657600080fd5b8101908080519060200190929190505050506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6020811015610cb757600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610dc057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a84836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166316a25cbd856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e3557600080fd5b505afa158015610e49573d6000803e3d6000fd5b505050506040513d6020811015610e5f57600080fd5b8101908080519060200190929190505050905060008167ffffffffffffffff1614610f2e57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166314ab903885836040518363ffffffff1660e01b8152600401808381526020018267ffffffffffffffff1667ffffffffffffffff16815260200192505050600060405180830381600087803b158015610f1557600080fd5b505af1158015610f29573d6000803e3d6000fd5b505050505b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148015610fb85750600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614155b15611562576060600080600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632eef3d658b60001b6040518060400160405280600881526020017fffffffffffffffff0000000000000000000000000000000000000000000000008152506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561108f578082015181840152602081019050611074565b50505050905090810190601f1680156110bc5780820380516001836020036101000a031916815260200191505b50935050505060006040518083038186803b1580156110da57600080fd5b505afa1580156110ee573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561111857600080fd5b810190808051604051939291908464010000000082111561113857600080fd5b8382019150602082018581111561114e57600080fd5b825186600182028301116401000000008211171561116b57600080fd5b8083526020830192505050908051906020019080838360005b8381101561119f578082015181840152602081019050611184565b50505050905090810190601f1680156111cc5780820380516001836020036101000a031916815260200191505b50604052602001805190602001909291908051906020019092919080519060200190929190505050935050925092506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be38c60001b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561127357600080fd5b505afa158015611287573d6000803e3d6000fd5b505050506040513d602081101561129d57600080fd5b8101908080519060200190929190505050905060008451141561130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f81526020018061181f602f913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156113d657600080fd5b505af11580156113ea573d6000803e3d6000fd5b50505050600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf7752558585858560006040518663ffffffff1660e01b815260040180806020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b838110156114f15780820151818401526020810190506114d6565b50505050905090810190601f16801561151e5780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561154157600080fd5b505af1158015611555573d6000803e3d6000fd5b5050505050505050611719565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c385856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561160b57600080fd5b505af115801561161f573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd30888a6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561170057600080fd5b505af1158015611714573d6000803e3d6000fd5b505050505b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59236008548960001b306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b1580156117cf57600080fd5b505af11580156117e3573d6000803e3d6000fd5b50505050505050505b505050565b6000813b19199050919050565b60008282111561180d57600080fd5b60008284039050809150509291505056fe556e61626c6520746f206d69677261746520646f6d61696e206f6e20737562646f6d61696e20726567697374726172a265627a7a72315820b05e53db00a2a204eca6f3819046763a6beae4c3485927af38753d4c4001aaeb64736f6c63430005100032
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
68380:4798:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68380:4798:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72446:295;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72446:295:0;;;;;;;;;;;;;;;;;:::i;:::-;;68726:17;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68588:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68645:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68750:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;71885:188;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71885:188:0;;;;;;;;;;;;;;;;;:::i;:::-;;68519:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;68812:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;72184:165;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72184:165:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;72184:165:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72184: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;72184:165:0;;;;;;;;;;;;:::i;:::-;;68699:20;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;72847:171;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72847:171:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;72847:171:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72847: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;72847:171:0;;;;;;;;;;;;:::i;:::-;;68876:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;72446:295;72503:19;72524:12;72545:15;;;;;;;;;;;:23;;;72569:5;72545:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72545:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72545:30:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;72545:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72502:73;;;;;;;72602:20;72594:28;;;;;;;;:4;:28;;;;;;;;;72586:37;;;;;;72634:13;72655:4;72650:16;;;:18;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72650:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72650:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72650:18:0;;;;;;;;;;;;;;;;72634:34;;72679:54;72699:5;72691:14;;72707:5;72714:18;;72679:11;:54::i;:::-;72446:295;;;;:::o;68726:17::-;;;;;;;;;;;;;:::o;68588:50::-;;;;;;;;;;;;;:::o;68645:47::-;;;;;;;;;;;;;:::o;68750:55::-;;;;;;;;;;;;;:::o;71885:188::-;71937:18;71958:12;;;;;;;;;;;:20;;;71979:7;71958:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71958:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71958:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71958:29:0;;;;;;;;;;;;;;;;71937:50;;71998:67;72010:7;72019:10;72031:12;;;;;;;;;;;:24;;;72056:7;72031:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72031:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72031:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72031:33:0;;;;;;;;;;;;;;;;71998:11;:67::i;:::-;71885:188;;:::o;68519:32::-;;;;;;;;;;;;;:::o;68812:55::-;;;;;;;;;;;;;:::o;72184:165::-;72257:6;72266:1;72257:10;;72253:89;72273:8;;:15;;72269:1;:19;72253:89;;;72310:20;72318:8;;72327:1;72318:11;;;;;;;;;;;;;72310:7;:20::i;:::-;72290:3;;;;;;;72253:89;;;;72184:165;;:::o;68699:20::-;;;;;;;;;;;;;:::o;72847:171::-;72924:6;72933:1;72924:10;;72920:91;72940:6;;:13;;72936:1;:17;72920:91;;;72975:24;72989:6;;72996:1;72989:9;;;;;;;;;;;;;72975:13;:24::i;:::-;72955:3;;;;;;;72920:91;;;;72847:171;;:::o;68876:23::-;;;;:::o;69563:2221::-;69655:12;69697:8;;69715:7;69707:16;;69680:44;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;69680:44:0;;;69670:55;;;;;;69655:70;;69736:18;69757:6;;;;;;;;;;;:12;;;69770:4;69757:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69757:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69757:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;69757:18:0;;;;;;;;;;;;;;;;69736:39;;69822:21;;;;;;;;;;;69791:53;;69799:10;69791:53;;;;:76;;;;;69848:19;69856:10;69848:7;:19::i;:::-;69791:76;69788:294;;;69985:12;;;;;;;;;;;:25;;;70011:7;70020:10;70032:16;70044:3;70032:7;:11;;:16;;;;:::i;:::-;69985:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69985:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69985:64:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;69985:64:0;;;;;;;;;;;;;;;;;70064:7;;;;69788:294;70171:12;;;;;;;;;;;:21;;;70193:7;70210:4;70217:16;70229:3;70217:7;:11;;:16;;;;:::i;:::-;70171:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70171:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70171:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;70171:63:0;;;;;;;;;;;;;;;;;70314:16;70333:6;;;;;;;;;;;:15;;;70349:4;70333:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70333:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70333:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;70333:21:0;;;;;;;;;;;;;;;;70314:40;;70388:1;70368:22;;:8;:22;;;70365:88;;70407:6;;;;;;;;;;;:18;;;70426:4;70432:8;70407:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70407:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70407:34:0;;;;70365:88;70465:10;70478:6;;;;;;;;;;;:10;;;70489:4;70478:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70478:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70478:16:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;70478:16:0;;;;;;;;;;;;;;;;70465:29;;70515:1;70508:3;:8;;;70505:64;;70533:6;;;;;;;;;;;:13;;;70547:4;70553:3;70533:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70533:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70533:24:0;;;;70505:64;70615:21;;;;;;;;;;;70584:53;;70592:10;70584:53;;;:90;;;;;70672:1;70641:33;;70649:10;70641:33;;;;70584:90;70581:1032;;;70803:19;70824:10;70837:19;70860:21;;;;;;;;;;;:27;;;70896:7;70888:16;;70913;;;;;;;;;;;;;;;;;70860: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;70860:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70860:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70860:71:0;;;;;;39:16:-1;36:1;17:17;2:54;70860: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;70860: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;;70860: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;70860:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70802:129;;;;;;;70946:13;70962:21;;;;;;;;;;;:27;;;70998:7;70990:16;;70962:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70962:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70962:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;70962:45:0;;;;;;;;;;;;;;;;70946:61;;71048:1;71031:5;71025:19;:24;71022:119;;;71068:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71022:119;71213:12;;;;;;;;;;;:20;;;71242:21;;;;;;;;;;;71266:7;71213:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71213:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71213:61:0;;;;71289:21;;;;;;;;;;;:40;;;71330:5;71337;71344:14;71376:5;71393:1;71289: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;71289:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71289:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71289:107:0;;;;70581:1032;;;;;;;71429:6;;;;;;;;;;;:15;;;71445:4;71451:10;71429:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71429:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71429:33:0;;;;71540:12;;;;;;;;;;;:25;;;71574:4;71581:10;71593:7;71540:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71540:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71540:61:0;;;;70581:1032;71711:6;;;;;;;;;;;:22;;;71734:8;;71752:7;71744:16;;71770:4;71711:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71711:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71711:65:0;;;;69563:2221;;;;;;;;:::o;73026:149::-;73078:8;73150:4;73138:17;73134:22;73130:27;73123:34;;73108: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://b05e53db00a2a204eca6f3819046763a6beae4c3485927af38753d4c4001aaeb
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.