ETH Price: $2,687.00 (-1.73%)

Contract

0xB8C78147E8951e3c06327740448F89560AD4f7EF
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Price168452692023-03-17 4:50:23529 days ago1679028623IN
0xB8C78147...60AD4f7EF
0 ETH0.005469917.84984569
Set Price167829422023-03-08 10:27:11537 days ago1678271231IN
0xB8C78147...60AD4f7EF
0 ETH0.0022170720.77939305
Set Whitelist167816222023-03-08 6:00:59538 days ago1678255259IN
0xB8C78147...60AD4f7EF
0 ETH0.0022608426.7609707
Set Whitelist167381972023-03-02 3:24:35544 days ago1677727475IN
0xB8C78147...60AD4f7EF
0 ETH0.003545625.07804622
Set Price167380072023-03-02 2:46:23544 days ago1677725183IN
0xB8C78147...60AD4f7EF
0 ETH0.0034172723.30382675
Buy Subnode Whit...166413092023-02-16 12:32:11557 days ago1676550731IN
0xB8C78147...60AD4f7EF
0.01 ETH0.0056313625.99412229
Buy Subnode166281242023-02-14 16:16:35559 days ago1676391395IN
0xB8C78147...60AD4f7EF
0.005 ETH0.0058506632.25549637
Set Price166280602023-02-14 16:03:47559 days ago1676390627IN
0xB8C78147...60AD4f7EF
0 ETH0.0033615437.6972968
Register Subnode166273662023-02-14 13:44:47559 days ago1676382287IN
0xB8C78147...60AD4f7EF
0 ETH0.0030679826.03385846
Buy Subnode166243062023-02-14 3:27:11560 days ago1676345231IN
0xB8C78147...60AD4f7EF
0 ETH0.0024401315.33731419
Buy Subnode166193352023-02-13 10:47:23560 days ago1676285243IN
0xB8C78147...60AD4f7EF
0.005 ETH0.0032290617.86015293
Buy Subnode Whit...166193312023-02-13 10:46:35560 days ago1676285195IN
0xB8C78147...60AD4f7EF
0.01 ETH0.003591718
Buy Subnode166057762023-02-11 13:20:23562 days ago1676121623IN
0xB8C78147...60AD4f7EF
0.0069 ETH0.0025216814.00546172
Buy Subnode Whit...166041202023-02-11 7:46:59562 days ago1676101619IN
0xB8C78147...60AD4f7EF
0 ETH0.003300116.90330723
Register Subnode166026612023-02-11 2:53:11563 days ago1676083991IN
0xB8C78147...60AD4f7EF
0 ETH0.0024064120.27516228
Register Subnode166026532023-02-11 2:51:35563 days ago1676083895IN
0xB8C78147...60AD4f7EF
0 ETH0.0023024819.39946357
Register Subnode166026252023-02-11 2:45:59563 days ago1676083559IN
0xB8C78147...60AD4f7EF
0 ETH0.0019778316.62298127
Register Subnode165894422023-02-09 6:34:35565 days ago1675924475IN
0xB8C78147...60AD4f7EF
0 ETH0.0011997222.49621738
Register Subnode165894412023-02-09 6:34:23565 days ago1675924463IN
0xB8C78147...60AD4f7EF
0 ETH0.0027526323.07013406
Set Price165879462023-02-09 1:34:11565 days ago1675906451IN
0xB8C78147...60AD4f7EF
0 ETH0.0070035322.84913815
Buy Subnode Whit...165757672023-02-07 8:39:35566 days ago1675759175IN
0xB8C78147...60AD4f7EF
0 ETH0.0042360723.89399663
Buy Subnode Whit...165757602023-02-07 8:38:11566 days ago1675759091IN
0xB8C78147...60AD4f7EF
0 ETH0.0039777522.4369372
Set Whitelist165746912023-02-07 5:01:59567 days ago1675746119IN
0xB8C78147...60AD4f7EF
0 ETH0.0066578754.97874494
Set Price165746462023-02-07 4:52:59567 days ago1675745579IN
0xB8C78147...60AD4f7EF
0 ETH0.0055157517.99523201
Buy Subnode Whit...165690222023-02-06 10:02:59567 days ago1675677779IN
0xB8C78147...60AD4f7EF
0 ETH0.0037629919.28575516
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
166413092023-02-16 12:32:11557 days ago1676550731
0xB8C78147...60AD4f7EF
0.00025 ETH
166413092023-02-16 12:32:11557 days ago1676550731
0xB8C78147...60AD4f7EF
0.00975 ETH
166281242023-02-14 16:16:35559 days ago1676391395
0xB8C78147...60AD4f7EF
0.000125 ETH
166281242023-02-14 16:16:35559 days ago1676391395
0xB8C78147...60AD4f7EF
0.004875 ETH
166193352023-02-13 10:47:23560 days ago1676285243
0xB8C78147...60AD4f7EF
0.000125 ETH
166193352023-02-13 10:47:23560 days ago1676285243
0xB8C78147...60AD4f7EF
0.004875 ETH
166193312023-02-13 10:46:35560 days ago1676285195
0xB8C78147...60AD4f7EF
0.00025 ETH
166193312023-02-13 10:46:35560 days ago1676285195
0xB8C78147...60AD4f7EF
0.00975 ETH
166057762023-02-11 13:20:23562 days ago1676121623
0xB8C78147...60AD4f7EF
0.0001725 ETH
166057762023-02-11 13:20:23562 days ago1676121623
0xB8C78147...60AD4f7EF
0.0067275 ETH
165439212023-02-02 21:53:47571 days ago1675374827
0xB8C78147...60AD4f7EF
0.001 ETH
165439212023-02-02 21:53:47571 days ago1675374827
0xB8C78147...60AD4f7EF
0.039 ETH
165399512023-02-02 8:33:23571 days ago1675326803
0xB8C78147...60AD4f7EF
0.00025 ETH
165399512023-02-02 8:33:23571 days ago1675326803
0xB8C78147...60AD4f7EF
0.00975 ETH
165399442023-02-02 8:31:59571 days ago1675326719
0xB8C78147...60AD4f7EF
0.00025 ETH
165399442023-02-02 8:31:59571 days ago1675326719
0xB8C78147...60AD4f7EF
0.00975 ETH
165399412023-02-02 8:31:23571 days ago1675326683
0xB8C78147...60AD4f7EF
0.00025 ETH
165399412023-02-02 8:31:23571 days ago1675326683
0xB8C78147...60AD4f7EF
0.00975 ETH
165334202023-02-01 10:38:11572 days ago1675247891
0xB8C78147...60AD4f7EF
0.000125 ETH
165334202023-02-01 10:38:11572 days ago1675247891
0xB8C78147...60AD4f7EF
0.004875 ETH
165320642023-02-01 6:05:23573 days ago1675231523
0xB8C78147...60AD4f7EF
0.00025 ETH
165320642023-02-01 6:05:23573 days ago1675231523
0xB8C78147...60AD4f7EF
0.00975 ETH
165320592023-02-01 6:04:23573 days ago1675231463
0xB8C78147...60AD4f7EF
0.00025 ETH
165320592023-02-01 6:04:23573 days ago1675231463
0xB8C78147...60AD4f7EF
0.00975 ETH
165320522023-02-01 6:02:59573 days ago1675231379
0xB8C78147...60AD4f7EF
0.00025 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DaoHallRegistrar

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-01-19
*/

// Sources flattened with hardhat v2.12.4 https://hardhat.org

// File contracts/interfaces/IDaoHallRegistry.sol



pragma solidity ^0.8.0;

struct NodeRecord{
    uint256 startTime;
    uint256[5] annualPrice;
    uint256[5] maxPrice;
    
    uint256 whitelistStartTime;
    uint256 whitelistParam;
    bytes32 whitelistRoot;
}

interface IDaoHallRegistry {
    function setRecord(bytes32 node, address owner, NodeRecord calldata record) external;
    function getRecord(bytes32 node, address owner) external view returns (NodeRecord memory);

    function setWhitelistClaimed(bytes32 node, address claimer, uint256 count) external;
    function getWhitelistClaimed(bytes32 node, address claimer) external view returns (uint256);
}


// File contracts/interfaces/IDaoHallController.sol



pragma solidity ^0.8.0;

interface IDaoHallController {
    function setSubnodeRecord(
        bytes32 node,
        string calldata label,
        address owner,
        address resolver,
        uint64 ttl,
        uint32 fuses,
        uint64 expiry
    ) external;

    function setSubnodeExpiry(bytes32 node, string calldata label, uint64 expiry) external;

    function getNameData(bytes32 labelhash) external view returns (address, uint64);

    function getNodeData(bytes32 node) external view returns (address, uint64);
}


// File contracts/registrar/ens/ENS.sol

pragma solidity >=0.8.4;

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 @openzeppelin/contracts/utils/introspection/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


// File @openzeppelin/contracts/token/ERC721/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}


// File contracts/registrar/ens/IBaseRegistrar.sol

interface IBaseRegistrar is IERC721 {
    event ControllerAdded(address indexed controller);
    event ControllerRemoved(address indexed controller);
    event NameMigrated(
        uint256 indexed id,
        address indexed owner,
        uint256 expires
    );
    event NameRegistered(
        uint256 indexed id,
        address indexed owner,
        uint256 expires
    );
    event NameRenewed(uint256 indexed id, uint256 expires);

    // 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 (uint256);

    // Returns true iff the specified name is available for registration.
    function available(uint256 id) external view returns (bool);

    /**
     * @dev Register a name.
     */
    function register(
        uint256 id,
        address owner,
        uint256 duration
    ) external returns (uint256);

    function renew(uint256 id, uint256 duration) external returns (uint256);

    /**
     * @dev Reclaim ownership of a name in ENS, if you own it in the registrar.
     */
    function reclaim(uint256 id, address owner) external;
}


// File contracts/registrar/ens/IMetadataService.sol

pragma solidity >=0.8.4;

interface IMetadataService {
    function uri(uint256) external view returns (string memory);
}


// File @openzeppelin/contracts/token/ERC1155/[email protected]


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}


// File contracts/registrar/ens/INameWrapper.sol


pragma solidity ~0.8.17;




uint32 constant CANNOT_UNWRAP = 1;
uint32 constant CANNOT_BURN_FUSES = 2;
uint32 constant CANNOT_TRANSFER = 4;
uint32 constant CANNOT_SET_RESOLVER = 8;
uint32 constant CANNOT_SET_TTL = 16;
uint32 constant CANNOT_CREATE_SUBDOMAIN = 32;
//uint16 reserved for parent controlled fuses from bit 17 to bit 32
uint32 constant PARENT_CANNOT_CONTROL = 1 << 16;
uint32 constant IS_DOT_ETH = 1 << 17;
uint32 constant CAN_EXTEND_EXPIRY = 1 << 18;
uint32 constant CAN_DO_EVERYTHING = 0;
uint32 constant PARENT_CONTROLLED_FUSES = 0xFFFF0000;
// all fuses apart from IS_DOT_ETH
uint32 constant USER_SETTABLE_FUSES = 0xFFFDFFFF;

interface INameWrapper is IERC1155 {
    event NameWrapped(
        bytes32 indexed node,
        bytes name,
        address owner,
        uint32 fuses,
        uint64 expiry
    );

    event NameUnwrapped(bytes32 indexed node, address owner);

    event FusesSet(bytes32 indexed node, uint32 fuses);
    event ExpiryExtended(bytes32 indexed node, uint64 expiry);

    function ens() external view returns (ENS);

    function registrar() external view returns (IBaseRegistrar);

    function metadataService() external view returns (IMetadataService);

    function names(bytes32) external view returns (bytes memory);

    function wrap(
        bytes calldata name,
        address wrappedOwner,
        address resolver
    ) external;

    function wrapETH2LD(
        string calldata label,
        address wrappedOwner,
        uint16 ownerControlledFuses,
        address resolver
    ) external;

    function registerAndWrapETH2LD(
        string calldata label,
        address wrappedOwner,
        uint256 duration,
        address resolver,
        uint16 ownerControlledFuses
    ) external returns (uint256 registrarExpiry);

    function renew(uint256 labelHash, uint256 duration)
        external
        returns (uint256 expires);

    function unwrap(
        bytes32 node,
        bytes32 label,
        address owner
    ) external;

    function unwrapETH2LD(
        bytes32 label,
        address newRegistrant,
        address newController
    ) external;

    function setFuses(bytes32 node, uint16 ownerControlledFuses)
        external
        returns (uint32 newFuses);

    function setChildFuses(
        bytes32 parentNode,
        bytes32 labelhash,
        uint32 fuses,
        uint64 expiry
    ) external;

    function setSubnodeRecord(
        bytes32 node,
        string calldata label,
        address owner,
        address resolver,
        uint64 ttl,
        uint32 fuses,
        uint64 expiry
    ) external returns (bytes32);

    function setRecord(
        bytes32 node,
        address owner,
        address resolver,
        uint64 ttl
    ) external;

    function setSubnodeOwner(
        bytes32 node,
        string calldata label,
        address newOwner,
        uint32 fuses,
        uint64 expiry
    ) external returns (bytes32);

    function extendExpiry(
        bytes32 node,
        bytes32 labelhash,
        uint64 expiry
    ) external returns (uint64);

    function canModifyName(bytes32 node, address addr) external returns (bool);

    function setResolver(bytes32 node, address resolver) external;

    function setTTL(bytes32 node, uint64 ttl) external;

    function ownerOf(uint256 id) external view returns (address owner);

    function getData(uint256 id)
        external view
        returns (
            address,
            uint32,
            uint64
        );

    function allFusesBurned(bytes32 node, uint32 fuseMask)
        external
        view
        returns (bool);
}


// File contracts/registrar/ens/Resolver.sol

pragma solidity >=0.8.4;

interface Resolver {
    event AddrChanged(bytes32 indexed node, address a);
    event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
    event NameChanged(bytes32 indexed node, string name);
    event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
    event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
    event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);
    event ContenthashChanged(bytes32 indexed node, bytes hash);
    /* Deprecated events */
    event ContentChanged(bytes32 indexed node, bytes32 hash);

    function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory);
    function addr(bytes32 node) external view returns (address);
    function addr(bytes32 node, uint coinType) external view returns(bytes memory);
    function contenthash(bytes32 node) external view returns (bytes memory);
    function dnsrr(bytes32 node) external view returns (bytes memory);
    function name(bytes32 node) external view returns (string memory);
    function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);
    function text(bytes32 node, string calldata key) external view returns (string memory);
    function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address);

    function setABI(bytes32 node, uint256 contentType, bytes calldata data) external;
    function setAddr(bytes32 node, address addr) external;
    function setAddr(bytes32 node, uint coinType, bytes calldata a) external;
    function setContenthash(bytes32 node, bytes calldata hash) external;
    function setDnsrr(bytes32 node, bytes calldata data) external;
    function setName(bytes32 node, string calldata _name) external;
    function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;
    function setText(bytes32 node, string calldata key, string calldata value) external;
    function setInterface(bytes32 node, bytes4 interfaceID, address implementer) external;

    function supportsInterface(bytes4 interfaceID) external pure returns (bool);

    /* Deprecated functions */
    function content(bytes32 node) external view returns (bytes32);
    function multihash(bytes32 node) external view returns (bytes memory);
    function setContent(bytes32 node, bytes32 hash) external;
    function setMultihash(bytes32 node, bytes calldata hash) external;
}


// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}


// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


// File @openzeppelin/contracts/access/[email protected]


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}


// File contracts/registrar/DaoHallRegistrar.sol


pragma solidity ~0.8.17;
uint32 constant FLAG_AVAILABLE = 1;
uint32 constant FLAG_LOCKED = 2;

error PriceLocked(bytes32 node, uint i);
error PriceAlreadyAvailable(bytes32 node, uint i);
error PriceNotAvailable(bytes32 node, uint i);

contract DaoHallRegistrar is Ownable{
  using Address for address;

  bytes32 private constant ETH_NODE = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;

  IDaoHallRegistry public daoHallRegistry;
  IDaoHallController public ensController;
  IDaoHallController public wrapperController;
  INameWrapper public wrapper;
  ENS public immutable ens;
  IBaseRegistrar public immutable registrar;
  uint32 public immutable feeRate = 250;
  address public feeReceiver;

  event NodeUpdated(bytes32 node, address operator);
  event SubnodeSale(string label, bytes32 parentNode, address buyer, uint32 duration, uint256 price);
  event SubnodeExtended(string label, bytes32 parentNode, address buyer, uint32 duration, uint256 price);

  constructor(
    IDaoHallRegistry _daoHallRegistry,
    IDaoHallController _ensController,
    IDaoHallController _wrapperController,
    INameWrapper _wrapper,
    ENS _ens,
    IBaseRegistrar _registrar,
    address _feeReceiver
  ) {
    daoHallRegistry = _daoHallRegistry;
    ensController = _ensController;
    wrapperController = _wrapperController;
    wrapper = _wrapper;
    ens = _ens;
    registrar = _registrar;
    feeReceiver = _feeReceiver;
  }
  
  function setNameWrapper(INameWrapper _wrapper, IDaoHallController _wrapperController) external onlyOwner {
    wrapper = _wrapper;
    wrapperController = _wrapperController;
  }

  // Permits modifications only by the owner of the specified node.
  modifier authorised(bytes32 labelhash) {
    require(_isAuthorised(labelhash, msg.sender), "Unauthorised");
    _;
  }

  function _isAuthorised(bytes32 labelhash, address operator) internal view returns (bool) {
    if(isWrapped(labelhash)){
      address owner = wrapper.ownerOf(uint256(_l2Node(labelhash)));
      return owner == operator || wrapper.isApprovedForAll(owner, operator);
    }
    else{
      address owner = registrar.ownerOf(uint256(labelhash));
      return owner == operator || registrar.isApprovedForAll(owner, operator);
    }
  }

  function _setPrice(bytes32 node, uint256 startTime, uint256[5] calldata annualPrice, uint256[5] calldata maxPrice) internal{
    NodeRecord memory record = daoHallRegistry.getRecord(node, msg.sender);
    record.startTime = startTime;
    for(uint i = 0; i < 5; i ++){
      if(isLocked(record.annualPrice[i])){
        // record locked
        if(record.annualPrice[i] != annualPrice[i] || record.maxPrice[i] != maxPrice[i]){
          revert PriceLocked(node, i);
        }
        continue;
      }
      if(isAvailable(record.annualPrice[i]) && !isAvailable(annualPrice[i])){
        revert PriceAlreadyAvailable(node, i);
      }
      if(isAvailable(record.maxPrice[i]) && !isAvailable(maxPrice[i])){
        revert PriceAlreadyAvailable(node, i);
      }
      record.annualPrice[i] = annualPrice[i];
      record.maxPrice[i] = maxPrice[i];
    }
    daoHallRegistry.setRecord(node, msg.sender, record);
  }

  function _setWhitelist(bytes32 node, uint256 startTime, uint256 param, bytes32 root) internal{
    NodeRecord memory record = daoHallRegistry.getRecord(node, msg.sender);
    record.whitelistStartTime = startTime;
    record.whitelistParam = param;
    record.whitelistRoot = root;
    daoHallRegistry.setRecord(node, msg.sender, record);
  }

  function setPrice(bytes32 labelhash, uint256 startTime, uint256[5] calldata annualPrice, uint256[5] calldata maxPrice) external authorised(labelhash){
    bytes32 node = _l2Node(labelhash);
    _setPrice(node, startTime, annualPrice, maxPrice);
    emit NodeUpdated(node, msg.sender);
  }

  function setWhitelist(bytes32 labelhash, uint256 startTime, uint256 param, bytes32 root) external authorised(labelhash){
    bytes32 node = _l2Node(labelhash);
    _setWhitelist(node, startTime, param, root);
    emit NodeUpdated(node, msg.sender);
  }

  function setRecord(bytes32 labelhash, NodeRecord calldata record) external authorised(labelhash) {
    bytes32 node = _l2Node(labelhash);
    _setPrice(node, record.startTime, record.annualPrice, record.maxPrice);
    _setWhitelist(node, record.whitelistStartTime, record.whitelistParam, record.whitelistRoot);
    emit NodeUpdated(node, msg.sender);
  }

  function getRecord(bytes32 node, address owner) public view returns (NodeRecord memory) {
    return daoHallRegistry.getRecord(node, owner);
  }

  function getRecord(bytes32 labelhash) public view returns (NodeRecord memory) {
    bytes32 node = _l2Node(labelhash);
    address owner = isWrapped(labelhash) ? wrapper.ownerOf(uint256(node)) : registrar.ownerOf(uint256(labelhash));
    return daoHallRegistry.getRecord(node, owner);
  }

  function whitelistClaimed(bytes32 node, address claimer) public view returns (uint256){
    return daoHallRegistry.getWhitelistClaimed(node, claimer);
  }

  function isWrapped(bytes32 labelhash) public view returns (bool) {
    address owner = registrar.ownerOf(uint256(labelhash));
    return owner != address(0) && owner == address(wrapper);
  }

  function controllerOf(bytes32 labelhash) public view returns (IDaoHallController) {
    return isWrapped(labelhash) ? wrapperController : ensController;
  }

  function buySubnode(string memory label, bytes32 parentHash, address resolver, uint64 ttl, uint32 fuses, uint32 duration) external payable {
    _checkBuy(label, parentHash, duration);
    _buy(label, parentHash, resolver, ttl, fuses, msg.value, duration);
  }

  function buySubnodeWhitelisted(string memory label, bytes32 parentHash, address resolver, uint64 ttl, uint32 fuses, bytes32[] calldata proof, uint64 data) external payable {
    uint32 duration = uint32(data);
    _checkBuyWhitelisted(label, parentHash, duration, proof, uint32(data >> 32));
    _buy(label, parentHash, resolver, ttl, fuses, msg.value, duration);
  }

  function extendSubnode(string memory label, bytes32 parentHash, uint32 duration) external payable {
    IDaoHallController controller = controllerOf(parentHash);
    // check for subnode
    bytes32 parentNode = _l2Node(parentHash);
    bytes32 node = _makeNode(parentNode, keccak256(bytes(label)));
    (address owner, uint64 oldExpiry) = controller.getNodeData(node);
    require(owner != address(0), "No such subnode");

    (address parentOwner, uint64 parentExpiry) = controller.getNameData(parentHash);
    NodeRecord memory record = daoHallRegistry.getRecord(parentNode, parentOwner);

    if(!_isAuthorised(parentHash, msg.sender)){
      require(msg.value == _calculatePrice(record, parentHash, unicodeLength(label), duration), "Invalid price");
    }

    uint64 newExpiry = parentExpiry;    
    if(duration > 0){
      newExpiry = uint64(oldExpiry + (duration * 365 days));
      require(newExpiry <= parentExpiry, "Invalid duration");
    }

    if(msg.value > 0){
      _processFee(msg.value, parentOwner);
    }      
    controller.setSubnodeExpiry(parentNode, label, newExpiry);
    emit SubnodeExtended(label, parentNode, msg.sender, duration, msg.value);
  }

  function registerSubnode(string memory label, bytes32 parentHash, address resolver, uint64 ttl, uint32 fuses, uint32 duration) external authorised(parentHash){
    require(unicodeLength(label) > 0, "Empty label");
    _buy(label, parentHash, resolver, ttl, fuses, 0, duration);
  }

  function wrapSubnode(string memory label, bytes32 parentNode) external {
    bytes32 node = _makeNode(parentNode, keccak256(bytes(label)));
    (address owner, uint64 expiry) = ensController.getNodeData(node);
    require(owner == msg.sender || ens.isApprovedForAll(owner, msg.sender), "Unauthorised");

    wrapperController.setSubnodeRecord(parentNode, label, owner, ens.resolver(node), ens.ttl(node), 0, expiry);
  }

  function _calculatePrice(NodeRecord memory record, bytes32 parentHash, uint256 length, uint32 duration) internal pure returns (uint256) {
    uint256 index = length > 5 ? 4 : length - 1;
    uint256 price = duration == 0 ? record.maxPrice[index] : record.annualPrice[index];
    if(!isAvailable(price)){
      revert PriceNotAvailable(_l2Node(parentHash), index);
    }
    price = getValue(price);
    return duration > 0 ? price * duration : price;
  }

  function _calculatePriceWhitelisted(NodeRecord memory record, bytes32 parentHash, uint256 length, uint32 duration) internal pure returns (uint256) {
    // check discount
    uint8 discount = whitelistDiscount(record.whitelistParam, length);
    require(discount <= 100, "Not available");
    return _calculatePrice(record, parentHash, length, duration) * (100 - discount) / 100;
  }

  function _checkBuy(string memory label, bytes32 parentHash, uint32 duration) internal {
    NodeRecord memory record = getRecord(parentHash);
    require(record.startTime > 0 && record.startTime <= block.timestamp, "Not for sale");
    uint256 len = unicodeLength(label);
    require(len > 0, "Empty label");
    
    // check amount
    uint256 price = _calculatePrice(record, parentHash, len, duration);
    require(msg.value == price, "Invalid price");
  }

  function _checkBuyWhitelisted(string memory label, bytes32 parentHash, uint32 duration, bytes32[] calldata proof, uint32 limit) internal {
    NodeRecord memory record = getRecord(parentHash);
    require(record.whitelistStartTime > 0 && record.whitelistStartTime <= block.timestamp, "Not for sale");
    require(bytes(label).length > 0, "Empty label");

    bytes32 parentNode = _l2Node(parentHash);
    uint256 claimed = daoHallRegistry.getWhitelistClaimed(parentNode, msg.sender);
    require(claimed < limit, "Address has claimed");

    uint16 maxDuration = whitelistMaxDuration(record.whitelistParam);
    require(maxDuration == 0 || (duration > 0 && duration <= maxDuration), "Exceed Max Duration");
    
    // check amount
    uint256 price =  _calculatePriceWhitelisted(record, parentHash, unicodeLength(label), duration);
    require(msg.value == price, "Invalid price");

    bytes32 leaf = keccak256(abi.encodePacked(msg.sender, bytes4(limit)));
    require(MerkleProof.verify(proof, record.whitelistRoot, leaf), "Invalid proof");
    daoHallRegistry.setWhitelistClaimed(parentNode, msg.sender, claimed + 1);
  }

  function _checkAvailability(bytes32 node, IDaoHallController controller) internal view {
    (address owner, uint64 expiry) = controller.getNodeData(node);
    require(owner == address(0) || expiry < block.timestamp, "Subnode not available");
  }

  function _buy(string memory label, bytes32 parentHash, address resolver, uint64 ttl, uint32 fuses, uint256 price, uint32 duration) internal{
    IDaoHallController controller = controllerOf(parentHash);
    bytes32 parentNode = _l2Node(parentHash);
    bytes32 node = _makeNode(parentNode, keccak256(bytes(label)));
    // check availability
    _checkAvailability(node, controller);

    // check expiry date
    (address parentOwner, uint64 parentExpiry) = controller.getNameData(parentHash);
    uint64 childExpiry = parentExpiry;
    if(duration > 0){
      childExpiry = uint64(block.timestamp + (duration * 365 days));
      require(childExpiry <= parentExpiry, "Invalid duration");
    }
    
    if(price > 0){
      _processFee(price, parentOwner);
    }
    if(resolver != address(0)){
      // set this contract as the temporary owner, giving it permission to setup resolver
      controller.setSubnodeRecord(parentNode, label, address(this), resolver, ttl, fuses, childExpiry);
      Resolver(resolver).setAddr(node, msg.sender);
    }
    controller.setSubnodeRecord(parentNode, label, msg.sender, resolver, ttl, fuses, childExpiry);
    emit SubnodeSale(label, parentNode, msg.sender, duration, price);
  }

  function _processFee(uint256 price, address owner) internal {
    uint256 fee = price * feeRate / 10000;
    uint256 amount = price - fee;
    Address.sendValue(payable(owner), amount);
    Address.sendValue(payable(feeReceiver), fee);
  }

  function _makeNode(bytes32 node, bytes32 labelhash) private pure returns (bytes32){
    return keccak256(abi.encodePacked(node, labelhash));
  }

  function _l2Node(bytes32 labelhash) private pure returns (bytes32){
    return _makeNode(ETH_NODE, labelhash);
  }

  function setFeeReceiver(address _feeReceiver) external onlyOwner {
    feeReceiver = _feeReceiver;
  }

  function withdraw(uint256 amount, address receiver) external onlyOwner {
    Address.sendValue(payable(receiver), amount);
  }

  function getValue(uint256 price) public pure returns (uint256){
    return uint224(price);
  }

  function isAvailable(uint256 price) public pure returns(bool){
    return hasFlag(price, FLAG_AVAILABLE);
  }

  function isLocked(uint256 price) public pure returns (bool){
    return hasFlag(price, FLAG_LOCKED);
  }

  function hasFlag(uint256 price, uint32 flag) public pure returns (bool){
    return (uint32(price >> 224) & flag) > 0;
  }

  function whitelistDiscount(uint256 param, uint256 length) public pure returns (uint8){
    uint256 index = length > 5 ? 4 : length - 1;
    return uint8(param >> (index*8));
  }

  function whitelistMaxDuration(uint256 param) public pure returns (uint16){
    return uint16(param >> (40));
  }

  function unicodeLength(string memory str) public pure returns (uint256){
    bytes memory bs = bytes(str);
    uint256 len = bs.length;
    uint256 i = 0;
    uint256 result = 0;
    while(i < len){
        result ++;
        uint8 ch = uint8(bs[i]);
        if(ch < 0x80){
            i ++;
        }
        else if(ch < 0xe0){
            i += 2;
        }
        else if(ch < 0xf0){
            i += 3;
        }
        else{
            i += 4;
        }
    }
    return result;
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IDaoHallRegistry","name":"_daoHallRegistry","type":"address"},{"internalType":"contract IDaoHallController","name":"_ensController","type":"address"},{"internalType":"contract IDaoHallController","name":"_wrapperController","type":"address"},{"internalType":"contract INameWrapper","name":"_wrapper","type":"address"},{"internalType":"contract ENS","name":"_ens","type":"address"},{"internalType":"contract IBaseRegistrar","name":"_registrar","type":"address"},{"internalType":"address","name":"_feeReceiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"i","type":"uint256"}],"name":"PriceAlreadyAvailable","type":"error"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"i","type":"uint256"}],"name":"PriceLocked","type":"error"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"i","type":"uint256"}],"name":"PriceNotAvailable","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"NodeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"label","type":"string"},{"indexed":false,"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint32","name":"duration","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"SubnodeExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"label","type":"string"},{"indexed":false,"internalType":"bytes32","name":"parentNode","type":"bytes32"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint32","name":"duration","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"SubnodeSale","type":"event"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint32","name":"duration","type":"uint32"}],"name":"buySubnode","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint64","name":"data","type":"uint64"}],"name":"buySubnodeWhitelisted","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"}],"name":"controllerOf","outputs":[{"internalType":"contract IDaoHallController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoHallRegistry","outputs":[{"internalType":"contract IDaoHallRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ens","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ensController","outputs":[{"internalType":"contract IDaoHallController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"internalType":"uint32","name":"duration","type":"uint32"}],"name":"extendSubnode","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"feeRate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"}],"name":"getRecord","outputs":[{"components":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256[5]","name":"annualPrice","type":"uint256[5]"},{"internalType":"uint256[5]","name":"maxPrice","type":"uint256[5]"},{"internalType":"uint256","name":"whitelistStartTime","type":"uint256"},{"internalType":"uint256","name":"whitelistParam","type":"uint256"},{"internalType":"bytes32","name":"whitelistRoot","type":"bytes32"}],"internalType":"struct NodeRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"getRecord","outputs":[{"components":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256[5]","name":"annualPrice","type":"uint256[5]"},{"internalType":"uint256[5]","name":"maxPrice","type":"uint256[5]"},{"internalType":"uint256","name":"whitelistStartTime","type":"uint256"},{"internalType":"uint256","name":"whitelistParam","type":"uint256"},{"internalType":"bytes32","name":"whitelistRoot","type":"bytes32"}],"internalType":"struct NodeRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"getValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint32","name":"flag","type":"uint32"}],"name":"hasFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"isAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"}],"name":"isWrapped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"},{"internalType":"uint32","name":"fuses","type":"uint32"},{"internalType":"uint32","name":"duration","type":"uint32"}],"name":"registerSubnode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registrar","outputs":[{"internalType":"contract IBaseRegistrar","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeReceiver","type":"address"}],"name":"setFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract INameWrapper","name":"_wrapper","type":"address"},{"internalType":"contract IDaoHallController","name":"_wrapperController","type":"address"}],"name":"setNameWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256[5]","name":"annualPrice","type":"uint256[5]"},{"internalType":"uint256[5]","name":"maxPrice","type":"uint256[5]"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"},{"components":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256[5]","name":"annualPrice","type":"uint256[5]"},{"internalType":"uint256[5]","name":"maxPrice","type":"uint256[5]"},{"internalType":"uint256","name":"whitelistStartTime","type":"uint256"},{"internalType":"uint256","name":"whitelistParam","type":"uint256"},{"internalType":"bytes32","name":"whitelistRoot","type":"bytes32"}],"internalType":"struct NodeRecord","name":"record","type":"tuple"}],"name":"setRecord","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"labelhash","type":"bytes32"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"param","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"unicodeLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"claimer","type":"address"}],"name":"whitelistClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"param","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"whitelistDiscount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"param","type":"uint256"}],"name":"whitelistMaxDuration","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes32","name":"parentNode","type":"bytes32"}],"name":"wrapSubnode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrapper","outputs":[{"internalType":"contract INameWrapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrapperController","outputs":[{"internalType":"contract IDaoHallController","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60e060405260fa60c0523480156200001657600080fd5b50604051620033963803806200339683398101604081905262000039916200011b565b6200004433620000b2565b600180546001600160a01b03199081166001600160a01b03998a16179091556002805482169789169790971790965560038054871695881695909517909455600480548616938716939093179092558416608052831660a052600580549092169216919091179055620001c6565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200011857600080fd5b50565b600080600080600080600060e0888a0312156200013757600080fd5b8751620001448162000102565b6020890151909750620001578162000102565b60408901519096506200016a8162000102565b60608901519095506200017d8162000102565b6080890151909450620001908162000102565b60a0890151909350620001a38162000102565b60c0890151909250620001b68162000102565b8091505092959891949750929550565b60805160a05160c0516131686200022e600039600081816104d40152611ceb0152600081816102b801528181610a1c015281816114560152818161180301526118ba015260008181610374015281816107cf01528181610890015261091101526131686000f3fe6080604052600436106101f85760003560e01c806390118dff1161010d578063d0d27b3d116100a0578063de968a661161006f578063de968a661461063e578063efdcd97414610651578063f2fde38b14610671578063f6aacfb114610691578063fd0cd0d9146106b157600080fd5b8063d0d27b3d146105be578063d2b4678b146105de578063d3be37ee146105fe578063dd7ac9cd1461061e57600080fd5b8063ab6a0d75116100dc578063ab6a0d751461053e578063ac210cc71461055e578063b3f006741461057e578063ba4ecbd81461059e57600080fd5b806390118dff146104af578063978bbdb9146104c2578063a40b1ee11461050b578063a8ac9a681461052b57600080fd5b80633f15457f11610190578063715018a61161015f578063715018a6146103f65780637877dc4d1461040b578063877e3b031461043f5780638d1613ed1461045f5780638da5cb5b1461049157600080fd5b80633f15457f1461036257806368445cad1461039657806369e56c7d146103b65780636d03b0b9146103d657600080fd5b80632b20e397116101cc5780632b20e397146102a65780632c8b3417146102f2578063327f667e146103225780633a178d991461034257600080fd5b8062f714ce146101fd5780630ff4c9161461021f5780632001ad9614610259578063213681cd14610279575b600080fd5b34801561020957600080fd5b5061021d610218366004612790565b6106d1565b005b34801561022b57600080fd5b5061024661023a3660046127c0565b6001600160e01b031690565b6040519081526020015b60405180910390f35b34801561026557600080fd5b5061021d61027436600461287b565b6106e7565b34801561028557600080fd5b506102996102943660046127c0565b6109e2565b604051610250919061292f565b3480156102b257600080fd5b506102da7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610250565b3480156102fe57600080fd5b5061031261030d366004612957565b610b7f565b6040519015158152602001610250565b34801561032e57600080fd5b5061021d61033d366004612983565b610b95565b34801561034e57600080fd5b5061031261035d3660046127c0565b610bcb565b34801561036e57600080fd5b506102da7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a257600080fd5b5061021d6103b13660046129c2565b610bd8565b3480156103c257600080fd5b506001546102da906001600160a01b031681565b3480156103e257600080fd5b506002546102da906001600160a01b031681565b34801561040257600080fd5b5061021d610c58565b34801561041757600080fd5b5061042c6104263660046127c0565b60281c90565b60405161ffff9091168152602001610250565b34801561044b57600080fd5b5061024661045a366004612790565b610c6c565b34801561046b57600080fd5b5061047f61047a366004612a0b565b610ce9565b60405160ff9091168152602001610250565b34801561049d57600080fd5b506000546001600160a01b03166102da565b61021d6104bd366004612a2d565b610d1f565b3480156104ce57600080fd5b506104f67f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610250565b34801561051757600080fd5b50610299610526366004612790565b6110a0565b61021d610539366004612aa3565b61111e565b34801561054a57600080fd5b50610246610559366004612b2e565b611140565b34801561056a57600080fd5b506004546102da906001600160a01b031681565b34801561058a57600080fd5b506005546102da906001600160a01b031681565b3480156105aa57600080fd5b5061021d6105b9366004612aa3565b6111ea565b3480156105ca57600080fd5b5061021d6105d9366004612b62565b611252565b3480156105ea57600080fd5b506102da6105f93660046127c0565b611292565b34801561060a57600080fd5b506003546102da906001600160a01b031681565b34801561062a57600080fd5b5061021d610639366004612b94565b6112c3565b61021d61064c366004612bce565b611363565b34801561065d57600080fd5b5061021d61066c366004612cbc565b61138b565b34801561067d57600080fd5b5061021d61068c366004612cbc565b6113b5565b34801561069d57600080fd5b506103126106ac3660046127c0565b61142e565b3480156106bd57600080fd5b506103126106cc3660046127c0565b61143b565b6106d96114f5565b6106e3818361154f565b5050565b6000610721828480519060200120604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60025460405163d37029ff60e01b81526004810183905291925060009182916001600160a01b03169063d37029ff906024016040805180830381865afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190612cd9565b90925090506001600160a01b03821633148061083a575060405163e985e9c560e01b81526001600160a01b0383811660048301523360248301527f0000000000000000000000000000000000000000000000000000000000000000169063e985e9c590604401602060405180830381865afa158015610816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083a9190612d08565b61085f5760405162461bcd60e51b815260040161085690612d2a565b60405180910390fd5b600354604051630178b8bf60e01b8152600481018590526001600160a01b03918216916324c1af44918791899187917f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190612d50565b6040516316a25cbd60e01b8152600481018a90527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906316a25cbd90602401602060405180830381865afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109849190612d6d565b6000886040518863ffffffff1660e01b81526004016109a99796959493929190612dd0565b600060405180830381600087803b1580156109c357600080fd5b505af11580156109d7573d6000803e3d6000fd5b505050505050505050565b6109ea61271b565b60006109f58361166d565b90506000610a028461143b565b610a94576040516331a9108f60e11b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8f9190612d50565b610aff565b600480546040516331a9108f60e11b81529182018490526001600160a01b031690636352211e90602401602060405180830381865afa158015610adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aff9190612d50565b60015460405163a40b1ee160e01b8152600481018590526001600160a01b03808416602483015292935091169063a40b1ee1906044016101c060405180830381865afa158015610b53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b779190612e9d565b949350505050565b63ffffffff60e083901c82161615155b92915050565b610b9d6114f5565b600480546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6000610b8f826001610b7f565b83610be381336116bf565b610bff5760405162461bcd60e51b815260040161085690612d2a565b6000610c0a8661166d565b9050610c18818686866118e9565b604080518281523360208201527f83a0bef1edc45f8cb8b3d446482c1908a091cb221e373e1372df3f6c535e5e06910160405180910390a1505050505050565b610c606114f5565b610c6a6000611bb1565b565b6001546040516331c7c7cf60e21b8152600481018490526001600160a01b038381166024830152600092169063c71f1f3c90604401602060405180830381865afa158015610cbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce29190612f25565b9392505050565b60008060058311610d0457610cff600184612f54565b610d07565b60045b9050610d14816008612f67565b9390931c9392505050565b6000610d2a83611292565b90506000610d378461166d565b90506000610d73828780519060200120604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b9050600080846001600160a01b031663d37029ff846040518263ffffffff1660e01b8152600401610da691815260200190565b6040805180830381865afa158015610dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de69190612cd9565b90925090506001600160a01b038216610e335760405162461bcd60e51b815260206004820152600f60248201526e4e6f2073756368207375626e6f646560881b6044820152606401610856565b6040516387da479160e01b81526004810188905260009081906001600160a01b038816906387da4791906024016040805180830381865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea09190612cd9565b60015460405163a40b1ee160e01b8152600481018a90526001600160a01b038085166024830152939550919350600092169063a40b1ee1906044016101c060405180830381865afa158015610ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1d9190612e9d565b9050610f298a336116bf565b610f5f57610f41818b610f3b8e611140565b8c611c01565b3414610f5f5760405162461bcd60e51b815260040161085690612f7e565b8163ffffffff8a1615610fe157610f7a8a6301e13380612fa5565b610f8a9063ffffffff1686612fcd565b9050826001600160401b0316816001600160401b03161115610fe15760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b210323ab930ba34b7b760811b6044820152606401610856565b3415610ff157610ff13485611cdc565b886001600160a01b03166383f0b47f898e846040518463ffffffff1660e01b815260040161102193929190612ff4565b600060405180830381600087803b15801561103b57600080fd5b505af115801561104f573d6000803e3d6000fd5b505050507f8ec84ddbd51482fed8139c8e2b4eb964f6754ee17cdf9e908ed613949a8f54488c89338d3460405161108a959493929190613026565b60405180910390a1505050505050505050505050565b6110a861271b565b60015460405163a40b1ee160e01b8152600481018590526001600160a01b0384811660248301529091169063a40b1ee1906044016101c060405180830381865afa1580156110fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce29190612e9d565b611129868683611d51565b61113886868686863487611e07565b505050505050565b8051600090829082805b828210156111e1578061115c8161306c565b915050600084838151811061117357611173613085565b016020015160f81c9050608081101561119857826111908161306c565b9350506111db565b60e08160ff1610156111b6576111af60028461309b565b92506111db565b60f08160ff1610156111cd576111af60038461309b565b6111d860048461309b565b92505b5061114a565b95945050505050565b846111f581336116bf565b6112115760405162461bcd60e51b815260040161085690612d2a565b600061121c88611140565b116112395760405162461bcd60e51b8152600401610856906130ae565b6112498787878787600088611e07565b50505050505050565b8361125d81336116bf565b6112795760405162461bcd60e51b815260040161085690612d2a565b60006112848661166d565b9050610c18818686866120fc565b600061129d8261143b565b6112b2576002546001600160a01b0316610b8f565b50506003546001600160a01b031690565b816112ce81336116bf565b6112ea5760405162461bcd60e51b815260040161085690612d2a565b60006112f58461166d565b905061130a8184356020860160c087016118e9565b61132581846101600135856101800135866101a001356120fc565b604080518281523360208201527f83a0bef1edc45f8cb8b3d446482c1908a091cb221e373e1372df3f6c535e5e06910160405180910390a150505050565b8061137c898983878763ffffffff602084901c166121bb565b6109d789898989893487611e07565b6113936114f5565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6113bd6114f5565b6001600160a01b0381166114225760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610856565b61142b81611bb1565b50565b6000610b8f826002610b7f565b6040516331a9108f60e11b81526004810182905260009081907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156114a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c99190612d50565b90506001600160a01b03811615801590610ce257506004546001600160a01b0390811691161492915050565b6000546001600160a01b03163314610c6a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610856565b8047101561159f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610856565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146115ec576040519150601f19603f3d011682016040523d82523d6000602084013e6115f1565b606091505b50509050806116685760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610856565b505050565b604080517f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60208083019190915281830184905282518083038401815260609092019092528051910120600090610b8f565b60006116ca8361143b565b156117ea576004546000906001600160a01b0316636352211e6116ec8661166d565b60405160e083901b6001600160e01b03191681526004810191909152602401602060405180830381865afa158015611728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174c9190612d50565b9050826001600160a01b0316816001600160a01b031614806117e257506004805460405163e985e9c560e01b81526001600160a01b0384811693820193909352858316602482015291169063e985e9c5906044015b602060405180830381865afa1580156117be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e29190612d08565b915050610b8f565b6040516331a9108f60e11b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015611852573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118769190612d50565b9050826001600160a01b0316816001600160a01b031614806117e2575060405163e985e9c560e01b81526001600160a01b03828116600483015284811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063e985e9c5906044016117a1565b60015460405163a40b1ee160e01b8152600481018690523360248201526000916001600160a01b03169063a40b1ee1906044016101c060405180830381865afa15801561193a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195e9190612e9d565b848152905060005b6005811015611b7c576119928260200151826005811061198857611988613085565b602002015161142e565b15611a33578381600581106119a9576119a9613085565b6020020135826020015182600581106119c4576119c4613085565b6020020151141580611a0657508281600581106119e3576119e3613085565b6020020135826040015182600581106119fe576119fe613085565b602002015114155b15611a2e57604051630ab1fd2360e31b81526004810187905260248101829052604401610856565b611b6a565b611a5682602001518260058110611a4c57611a4c613085565b6020020151610bcb565b8015611a7e5750611a7c848260058110611a7257611a72613085565b6020020135610bcb565b155b15611aa65760405163cffaa69560e01b81526004810187905260248101829052604401610856565b611abf82604001518260058110611a4c57611a4c613085565b8015611add5750611adb838260058110611a7257611a72613085565b155b15611b055760405163cffaa69560e01b81526004810187905260248101829052604401610856565b838160058110611b1757611b17613085565b602002013582602001518260058110611b3257611b32613085565b6020020152828160058110611b4957611b49613085565b602002013582604001518260058110611b6457611b64613085565b60200201525b80611b748161306c565b915050611966565b50600154604051633deeb14f60e11b81526001600160a01b0390911690637bdd629e906109a9908890339086906004016130d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060058411611c1c57611c17600185612f54565b611c1f565b60045b9050600063ffffffff841615611c4f5786602001518260058110611c4557611c45613085565b6020020151611c6b565b86604001518260058110611c6557611c65613085565b60200201515b9050611c7681610bcb565b611ca757611c838661166d565b60405163fca8658b60e01b8152600481019190915260248101839052604401610856565b6001600160e01b031663ffffffff8416611cc15780611cd1565b611cd163ffffffff851682612f67565b979650505050505050565b6000612710611d1163ffffffff7f00000000000000000000000000000000000000000000000000000000000000001685612f67565b611d1b91906130f7565b90506000611d298285612f54565b9050611d35838261154f565b600554611d4b906001600160a01b03168361154f565b50505050565b6000611d5c836109e2565b805190915015801590611d70575080514210155b611dab5760405162461bcd60e51b815260206004820152600c60248201526b4e6f7420666f722073616c6560a01b6044820152606401610856565b6000611db685611140565b905060008111611dd85760405162461bcd60e51b8152600401610856906130ae565b6000611de683868487611c01565b90508034146111385760405162461bcd60e51b815260040161085690612f7e565b6000611e1287611292565b90506000611e1f8861166d565b90506000611e5b828b80519060200120604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b9050611e678184612525565b6040516387da479160e01b8152600481018a905260009081906001600160a01b038616906387da4791906024016040805180830381865afa158015611eb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed49190612cd9565b90925090508063ffffffff871615611f5b57611ef4876301e13380612fa5565b611f049063ffffffff164261309b565b9050816001600160401b0316816001600160401b03161115611f5b5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b210323ab930ba34b7b760811b6044820152606401610856565b8715611f6b57611f6b8884611cdc565b6001600160a01b038b161561204457856001600160a01b03166324c1af44868f308f8f8f886040518863ffffffff1660e01b8152600401611fb29796959493929190612dd0565b600060405180830381600087803b158015611fcc57600080fd5b505af1158015611fe0573d6000803e3d6000fd5b505060405162d5fa2b60e81b8152600481018790523360248201526001600160a01b038e16925063d5fa2b009150604401600060405180830381600087803b15801561202b57600080fd5b505af115801561203f573d6000803e3d6000fd5b505050505b856001600160a01b03166324c1af44868f338f8f8f886040518863ffffffff1660e01b815260040161207c9796959493929190612dd0565b600060405180830381600087803b15801561209657600080fd5b505af11580156120aa573d6000803e3d6000fd5b505050507fe6c19a4d1d5866707f1228c93b673e2667e91ebff83e76dddee75353e938bb028d86338a8c6040516120e5959493929190613026565b60405180910390a150505050505050505050505050565b60015460405163a40b1ee160e01b8152600481018690523360248201526000916001600160a01b03169063a40b1ee1906044016101c060405180830381865afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121719190612e9d565b606081018590526080810184905260a08101839052600154604051633deeb14f60e11b81529192506001600160a01b031690637bdd629e906109a9908890339086906004016130d3565b60006121c6866109e2565b9050600081606001511180156121e0575042816060015111155b61221b5760405162461bcd60e51b815260206004820152600c60248201526b4e6f7420666f722073616c6560a01b6044820152606401610856565b600087511161223c5760405162461bcd60e51b8152600401610856906130ae565b60006122478761166d565b6001546040516331c7c7cf60e21b8152600481018390523360248201529192506000916001600160a01b039091169063c71f1f3c90604401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c09190612f25565b90508363ffffffff16811061230d5760405162461bcd60e51b81526020600482015260136024820152721059191c995cdcc81a185cc818db185a5b5959606a1b6044820152606401610856565b600061231d846080015160281c90565b905061ffff8116158061234b575060008863ffffffff1611801561234b57508061ffff168863ffffffff1611155b61238d5760405162461bcd60e51b815260206004820152601360248201527222bc31b2b2b21026b0bc10223ab930ba34b7b760691b6044820152606401610856565b60006123a3858b61239d8e611140565b8c6125f9565b90508034146123c45760405162461bcd60e51b815260040161085690612f7e565b6040516bffffffffffffffffffffffff193360601b1660208201526001600160e01b031960e088901b16603482015260009060380160405160208183030381529060405280519060200120905061245289898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050505060a088015183612689565b61248e5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610856565b600180546001600160a01b03169063ae25e92a90879033906124b190899061309b565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b0390911660248301526044820152606401600060405180830381600087803b1580156124ff57600080fd5b505af1158015612513573d6000803e3d6000fd5b50505050505050505050505050505050565b60405163d37029ff60e01b81526004810183905260009081906001600160a01b0384169063d37029ff906024016040805180830381865afa15801561256e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125929190612cd9565b90925090506001600160a01b03821615806125b5575042816001600160401b0316105b611d4b5760405162461bcd60e51b81526020600482015260156024820152745375626e6f6465206e6f7420617661696c61626c6560581b6044820152606401610856565b60008061260a866080015185610ce9565b905060648160ff1611156126505760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420617661696c61626c6560981b6044820152606401610856565b606461265c8282613119565b60ff1661266b88888888611c01565b6126759190612f67565b61267f91906130f7565b9695505050505050565b600082612696858461269f565b14949350505050565b600081815b84518110156126e4576126d0828683815181106126c3576126c3613085565b60200260200101516126ec565b9150806126dc8161306c565b9150506126a4565b509392505050565b6000818310612708576000828152602084905260409020610ce2565b6000838152602083905260409020610ce2565b6040518060c001604052806000815260200161273561275d565b815260200161274261275d565b81526000602082018190526040820181905260609091015290565b6040518060a001604052806005906020820280368337509192915050565b6001600160a01b038116811461142b57600080fd5b600080604083850312156127a357600080fd5b8235915060208301356127b58161277b565b809150509250929050565b6000602082840312156127d257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261280057600080fd5b81356001600160401b038082111561281a5761281a6127d9565b604051601f8301601f19908116603f01168101908282118183101715612842576128426127d9565b8160405283815286602085880101111561285b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561288e57600080fd5b82356001600160401b038111156128a457600080fd5b6128b0858286016127ef565b95602094909401359450505050565b8060005b6005811015611d4b5781518452602093840193909101906001016128c3565b8051825260208101516128f860208401826128bf565b50604081015161290b60c08401826128bf565b506060810151610160830152608081015161018083015260a001516101a090910152565b6101c08101610b8f82846128e2565b803563ffffffff8116811461295257600080fd5b919050565b6000806040838503121561296a57600080fd5b8235915061297a6020840161293e565b90509250929050565b6000806040838503121561299657600080fd5b82356129a18161277b565b915060208301356127b58161277b565b8060a08101831015610b8f57600080fd5b60008060008061018085870312156129d957600080fd5b84359350602085013592506129f186604087016129b1565b9150612a008660e087016129b1565b905092959194509250565b60008060408385031215612a1e57600080fd5b50508035926020909101359150565b600080600060608486031215612a4257600080fd5b83356001600160401b03811115612a5857600080fd5b612a64868287016127ef565b93505060208401359150612a7a6040850161293e565b90509250925092565b6001600160401b038116811461142b57600080fd5b803561295281612a83565b60008060008060008060c08789031215612abc57600080fd5b86356001600160401b03811115612ad257600080fd5b612ade89828a016127ef565b965050602087013594506040870135612af68161277b565b93506060870135612b0681612a83565b9250612b146080880161293e565b9150612b2260a0880161293e565b90509295509295509295565b600060208284031215612b4057600080fd5b81356001600160401b03811115612b5657600080fd5b610b77848285016127ef565b60008060008060808587031215612b7857600080fd5b5050823594602084013594506040840135936060013592509050565b6000808284036101e0811215612ba957600080fd5b833592506101c0601f1982011215612bc057600080fd5b506020830190509250929050565b60008060008060008060008060e0898b031215612bea57600080fd5b88356001600160401b0380821115612c0157600080fd5b612c0d8c838d016127ef565b995060208b0135985060408b01359150612c268261277b565b90965060608a013590612c3882612a83565b819650612c4760808c0161293e565b955060a08b0135915080821115612c5d57600080fd5b818b0191508b601f830112612c7157600080fd5b813581811115612c8057600080fd5b8c60208260051b8501011115612c9557600080fd5b602083019550809450505050612cad60c08a01612a98565b90509295985092959890939650565b600060208284031215612cce57600080fd5b8135610ce28161277b565b60008060408385031215612cec57600080fd5b8251612cf78161277b565b60208401519092506127b581612a83565b600060208284031215612d1a57600080fd5b81518015158114610ce257600080fd5b6020808252600c908201526b155b985d5d1a1bdc9a5cd95960a21b604082015260600190565b600060208284031215612d6257600080fd5b8151610ce28161277b565b600060208284031215612d7f57600080fd5b8151610ce281612a83565b6000815180845260005b81811015612db057602081850181015186830182015201612d94565b506000602082860101526020601f19601f83011685010191505092915050565b87815260e060208201526000612de960e0830189612d8a565b6001600160a01b0397881660408401529590961660608201526001600160401b03938416608082015263ffffffff9290921660a083015290911660c0909101529392505050565b600082601f830112612e4157600080fd5b60405160a081018181106001600160401b0382111715612e6357612e636127d9565b6040528060a0840185811115612e7857600080fd5b845b81811015612e92578051835260209283019201612e7a565b509195945050505050565b60006101c08284031215612eb057600080fd5b60405160c081018181106001600160401b0382111715612ed257612ed26127d9565b60405282518152612ee68460208501612e30565b6020820152612ef88460c08501612e30565b6040820152610160830151606082015261018083015160808201526101a09092015160a083015250919050565b600060208284031215612f3757600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610b8f57610b8f612f3e565b8082028115828204841417610b8f57610b8f612f3e565b6020808252600d908201526c496e76616c696420707269636560981b604082015260600190565b63ffffffff818116838216028082169190828114612fc557612fc5612f3e565b505092915050565b6001600160401b03818116838216019080821115612fed57612fed612f3e565b5092915050565b83815260606020820152600061300d6060830185612d8a565b90506001600160401b0383166040830152949350505050565b60a08152600061303960a0830188612d8a565b6020830196909652506001600160a01b0393909316604084015263ffffffff919091166060830152608090910152919050565b60006001820161307e5761307e612f3e565b5060010190565b634e487b7160e01b600052603260045260246000fd5b80820180821115610b8f57610b8f612f3e565b6020808252600b908201526a115b5c1d1e481b1858995b60aa1b604082015260600190565b8381526001600160a01b03831660208201526102008101610b7760408301846128e2565b60008261311457634e487b7160e01b600052601260045260246000fd5b500490565b60ff8281168282160390811115610b8f57610b8f612f3e56fea2646970667358221220a037b31ec1e705082799c5c6fd1e2cbeede0b4078a202915acb97fbfda67372164736f6c6343000811003300000000000000000000000031694f04e8e68c440cd4287ec147a566f038a14d000000000000000000000000febb6ff64cce7d26ad63194c338cb34eed628a6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85000000000000000000000000178bc6e45cab61e886cbd665f77dbd9615b0d70c

Deployed Bytecode

0x6080604052600436106101f85760003560e01c806390118dff1161010d578063d0d27b3d116100a0578063de968a661161006f578063de968a661461063e578063efdcd97414610651578063f2fde38b14610671578063f6aacfb114610691578063fd0cd0d9146106b157600080fd5b8063d0d27b3d146105be578063d2b4678b146105de578063d3be37ee146105fe578063dd7ac9cd1461061e57600080fd5b8063ab6a0d75116100dc578063ab6a0d751461053e578063ac210cc71461055e578063b3f006741461057e578063ba4ecbd81461059e57600080fd5b806390118dff146104af578063978bbdb9146104c2578063a40b1ee11461050b578063a8ac9a681461052b57600080fd5b80633f15457f11610190578063715018a61161015f578063715018a6146103f65780637877dc4d1461040b578063877e3b031461043f5780638d1613ed1461045f5780638da5cb5b1461049157600080fd5b80633f15457f1461036257806368445cad1461039657806369e56c7d146103b65780636d03b0b9146103d657600080fd5b80632b20e397116101cc5780632b20e397146102a65780632c8b3417146102f2578063327f667e146103225780633a178d991461034257600080fd5b8062f714ce146101fd5780630ff4c9161461021f5780632001ad9614610259578063213681cd14610279575b600080fd5b34801561020957600080fd5b5061021d610218366004612790565b6106d1565b005b34801561022b57600080fd5b5061024661023a3660046127c0565b6001600160e01b031690565b6040519081526020015b60405180910390f35b34801561026557600080fd5b5061021d61027436600461287b565b6106e7565b34801561028557600080fd5b506102996102943660046127c0565b6109e2565b604051610250919061292f565b3480156102b257600080fd5b506102da7f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea8581565b6040516001600160a01b039091168152602001610250565b3480156102fe57600080fd5b5061031261030d366004612957565b610b7f565b6040519015158152602001610250565b34801561032e57600080fd5b5061021d61033d366004612983565b610b95565b34801561034e57600080fd5b5061031261035d3660046127c0565b610bcb565b34801561036e57600080fd5b506102da7f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e81565b3480156103a257600080fd5b5061021d6103b13660046129c2565b610bd8565b3480156103c257600080fd5b506001546102da906001600160a01b031681565b3480156103e257600080fd5b506002546102da906001600160a01b031681565b34801561040257600080fd5b5061021d610c58565b34801561041757600080fd5b5061042c6104263660046127c0565b60281c90565b60405161ffff9091168152602001610250565b34801561044b57600080fd5b5061024661045a366004612790565b610c6c565b34801561046b57600080fd5b5061047f61047a366004612a0b565b610ce9565b60405160ff9091168152602001610250565b34801561049d57600080fd5b506000546001600160a01b03166102da565b61021d6104bd366004612a2d565b610d1f565b3480156104ce57600080fd5b506104f67f00000000000000000000000000000000000000000000000000000000000000fa81565b60405163ffffffff9091168152602001610250565b34801561051757600080fd5b50610299610526366004612790565b6110a0565b61021d610539366004612aa3565b61111e565b34801561054a57600080fd5b50610246610559366004612b2e565b611140565b34801561056a57600080fd5b506004546102da906001600160a01b031681565b34801561058a57600080fd5b506005546102da906001600160a01b031681565b3480156105aa57600080fd5b5061021d6105b9366004612aa3565b6111ea565b3480156105ca57600080fd5b5061021d6105d9366004612b62565b611252565b3480156105ea57600080fd5b506102da6105f93660046127c0565b611292565b34801561060a57600080fd5b506003546102da906001600160a01b031681565b34801561062a57600080fd5b5061021d610639366004612b94565b6112c3565b61021d61064c366004612bce565b611363565b34801561065d57600080fd5b5061021d61066c366004612cbc565b61138b565b34801561067d57600080fd5b5061021d61068c366004612cbc565b6113b5565b34801561069d57600080fd5b506103126106ac3660046127c0565b61142e565b3480156106bd57600080fd5b506103126106cc3660046127c0565b61143b565b6106d96114f5565b6106e3818361154f565b5050565b6000610721828480519060200120604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60025460405163d37029ff60e01b81526004810183905291925060009182916001600160a01b03169063d37029ff906024016040805180830381865afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190612cd9565b90925090506001600160a01b03821633148061083a575060405163e985e9c560e01b81526001600160a01b0383811660048301523360248301527f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e169063e985e9c590604401602060405180830381865afa158015610816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083a9190612d08565b61085f5760405162461bcd60e51b815260040161085690612d2a565b60405180910390fd5b600354604051630178b8bf60e01b8152600481018590526001600160a01b03918216916324c1af44918791899187917f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e1690630178b8bf90602401602060405180830381865afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190612d50565b6040516316a25cbd60e01b8152600481018a90527f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b0316906316a25cbd90602401602060405180830381865afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109849190612d6d565b6000886040518863ffffffff1660e01b81526004016109a99796959493929190612dd0565b600060405180830381600087803b1580156109c357600080fd5b505af11580156109d7573d6000803e3d6000fd5b505050505050505050565b6109ea61271b565b60006109f58361166d565b90506000610a028461143b565b610a94576040516331a9108f60e11b8152600481018590527f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea856001600160a01b031690636352211e90602401602060405180830381865afa158015610a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8f9190612d50565b610aff565b600480546040516331a9108f60e11b81529182018490526001600160a01b031690636352211e90602401602060405180830381865afa158015610adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aff9190612d50565b60015460405163a40b1ee160e01b8152600481018590526001600160a01b03808416602483015292935091169063a40b1ee1906044016101c060405180830381865afa158015610b53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b779190612e9d565b949350505050565b63ffffffff60e083901c82161615155b92915050565b610b9d6114f5565b600480546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6000610b8f826001610b7f565b83610be381336116bf565b610bff5760405162461bcd60e51b815260040161085690612d2a565b6000610c0a8661166d565b9050610c18818686866118e9565b604080518281523360208201527f83a0bef1edc45f8cb8b3d446482c1908a091cb221e373e1372df3f6c535e5e06910160405180910390a1505050505050565b610c606114f5565b610c6a6000611bb1565b565b6001546040516331c7c7cf60e21b8152600481018490526001600160a01b038381166024830152600092169063c71f1f3c90604401602060405180830381865afa158015610cbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce29190612f25565b9392505050565b60008060058311610d0457610cff600184612f54565b610d07565b60045b9050610d14816008612f67565b9390931c9392505050565b6000610d2a83611292565b90506000610d378461166d565b90506000610d73828780519060200120604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b9050600080846001600160a01b031663d37029ff846040518263ffffffff1660e01b8152600401610da691815260200190565b6040805180830381865afa158015610dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de69190612cd9565b90925090506001600160a01b038216610e335760405162461bcd60e51b815260206004820152600f60248201526e4e6f2073756368207375626e6f646560881b6044820152606401610856565b6040516387da479160e01b81526004810188905260009081906001600160a01b038816906387da4791906024016040805180830381865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea09190612cd9565b60015460405163a40b1ee160e01b8152600481018a90526001600160a01b038085166024830152939550919350600092169063a40b1ee1906044016101c060405180830381865afa158015610ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1d9190612e9d565b9050610f298a336116bf565b610f5f57610f41818b610f3b8e611140565b8c611c01565b3414610f5f5760405162461bcd60e51b815260040161085690612f7e565b8163ffffffff8a1615610fe157610f7a8a6301e13380612fa5565b610f8a9063ffffffff1686612fcd565b9050826001600160401b0316816001600160401b03161115610fe15760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b210323ab930ba34b7b760811b6044820152606401610856565b3415610ff157610ff13485611cdc565b886001600160a01b03166383f0b47f898e846040518463ffffffff1660e01b815260040161102193929190612ff4565b600060405180830381600087803b15801561103b57600080fd5b505af115801561104f573d6000803e3d6000fd5b505050507f8ec84ddbd51482fed8139c8e2b4eb964f6754ee17cdf9e908ed613949a8f54488c89338d3460405161108a959493929190613026565b60405180910390a1505050505050505050505050565b6110a861271b565b60015460405163a40b1ee160e01b8152600481018590526001600160a01b0384811660248301529091169063a40b1ee1906044016101c060405180830381865afa1580156110fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce29190612e9d565b611129868683611d51565b61113886868686863487611e07565b505050505050565b8051600090829082805b828210156111e1578061115c8161306c565b915050600084838151811061117357611173613085565b016020015160f81c9050608081101561119857826111908161306c565b9350506111db565b60e08160ff1610156111b6576111af60028461309b565b92506111db565b60f08160ff1610156111cd576111af60038461309b565b6111d860048461309b565b92505b5061114a565b95945050505050565b846111f581336116bf565b6112115760405162461bcd60e51b815260040161085690612d2a565b600061121c88611140565b116112395760405162461bcd60e51b8152600401610856906130ae565b6112498787878787600088611e07565b50505050505050565b8361125d81336116bf565b6112795760405162461bcd60e51b815260040161085690612d2a565b60006112848661166d565b9050610c18818686866120fc565b600061129d8261143b565b6112b2576002546001600160a01b0316610b8f565b50506003546001600160a01b031690565b816112ce81336116bf565b6112ea5760405162461bcd60e51b815260040161085690612d2a565b60006112f58461166d565b905061130a8184356020860160c087016118e9565b61132581846101600135856101800135866101a001356120fc565b604080518281523360208201527f83a0bef1edc45f8cb8b3d446482c1908a091cb221e373e1372df3f6c535e5e06910160405180910390a150505050565b8061137c898983878763ffffffff602084901c166121bb565b6109d789898989893487611e07565b6113936114f5565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6113bd6114f5565b6001600160a01b0381166114225760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610856565b61142b81611bb1565b50565b6000610b8f826002610b7f565b6040516331a9108f60e11b81526004810182905260009081907f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea856001600160a01b031690636352211e90602401602060405180830381865afa1580156114a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c99190612d50565b90506001600160a01b03811615801590610ce257506004546001600160a01b0390811691161492915050565b6000546001600160a01b03163314610c6a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610856565b8047101561159f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610856565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146115ec576040519150601f19603f3d011682016040523d82523d6000602084013e6115f1565b606091505b50509050806116685760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610856565b505050565b604080517f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60208083019190915281830184905282518083038401815260609092019092528051910120600090610b8f565b60006116ca8361143b565b156117ea576004546000906001600160a01b0316636352211e6116ec8661166d565b60405160e083901b6001600160e01b03191681526004810191909152602401602060405180830381865afa158015611728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174c9190612d50565b9050826001600160a01b0316816001600160a01b031614806117e257506004805460405163e985e9c560e01b81526001600160a01b0384811693820193909352858316602482015291169063e985e9c5906044015b602060405180830381865afa1580156117be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e29190612d08565b915050610b8f565b6040516331a9108f60e11b8152600481018490526000907f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea856001600160a01b031690636352211e90602401602060405180830381865afa158015611852573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118769190612d50565b9050826001600160a01b0316816001600160a01b031614806117e2575060405163e985e9c560e01b81526001600160a01b03828116600483015284811660248301527f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85169063e985e9c5906044016117a1565b60015460405163a40b1ee160e01b8152600481018690523360248201526000916001600160a01b03169063a40b1ee1906044016101c060405180830381865afa15801561193a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195e9190612e9d565b848152905060005b6005811015611b7c576119928260200151826005811061198857611988613085565b602002015161142e565b15611a33578381600581106119a9576119a9613085565b6020020135826020015182600581106119c4576119c4613085565b6020020151141580611a0657508281600581106119e3576119e3613085565b6020020135826040015182600581106119fe576119fe613085565b602002015114155b15611a2e57604051630ab1fd2360e31b81526004810187905260248101829052604401610856565b611b6a565b611a5682602001518260058110611a4c57611a4c613085565b6020020151610bcb565b8015611a7e5750611a7c848260058110611a7257611a72613085565b6020020135610bcb565b155b15611aa65760405163cffaa69560e01b81526004810187905260248101829052604401610856565b611abf82604001518260058110611a4c57611a4c613085565b8015611add5750611adb838260058110611a7257611a72613085565b155b15611b055760405163cffaa69560e01b81526004810187905260248101829052604401610856565b838160058110611b1757611b17613085565b602002013582602001518260058110611b3257611b32613085565b6020020152828160058110611b4957611b49613085565b602002013582604001518260058110611b6457611b64613085565b60200201525b80611b748161306c565b915050611966565b50600154604051633deeb14f60e11b81526001600160a01b0390911690637bdd629e906109a9908890339086906004016130d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060058411611c1c57611c17600185612f54565b611c1f565b60045b9050600063ffffffff841615611c4f5786602001518260058110611c4557611c45613085565b6020020151611c6b565b86604001518260058110611c6557611c65613085565b60200201515b9050611c7681610bcb565b611ca757611c838661166d565b60405163fca8658b60e01b8152600481019190915260248101839052604401610856565b6001600160e01b031663ffffffff8416611cc15780611cd1565b611cd163ffffffff851682612f67565b979650505050505050565b6000612710611d1163ffffffff7f00000000000000000000000000000000000000000000000000000000000000fa1685612f67565b611d1b91906130f7565b90506000611d298285612f54565b9050611d35838261154f565b600554611d4b906001600160a01b03168361154f565b50505050565b6000611d5c836109e2565b805190915015801590611d70575080514210155b611dab5760405162461bcd60e51b815260206004820152600c60248201526b4e6f7420666f722073616c6560a01b6044820152606401610856565b6000611db685611140565b905060008111611dd85760405162461bcd60e51b8152600401610856906130ae565b6000611de683868487611c01565b90508034146111385760405162461bcd60e51b815260040161085690612f7e565b6000611e1287611292565b90506000611e1f8861166d565b90506000611e5b828b80519060200120604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b9050611e678184612525565b6040516387da479160e01b8152600481018a905260009081906001600160a01b038616906387da4791906024016040805180830381865afa158015611eb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed49190612cd9565b90925090508063ffffffff871615611f5b57611ef4876301e13380612fa5565b611f049063ffffffff164261309b565b9050816001600160401b0316816001600160401b03161115611f5b5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b210323ab930ba34b7b760811b6044820152606401610856565b8715611f6b57611f6b8884611cdc565b6001600160a01b038b161561204457856001600160a01b03166324c1af44868f308f8f8f886040518863ffffffff1660e01b8152600401611fb29796959493929190612dd0565b600060405180830381600087803b158015611fcc57600080fd5b505af1158015611fe0573d6000803e3d6000fd5b505060405162d5fa2b60e81b8152600481018790523360248201526001600160a01b038e16925063d5fa2b009150604401600060405180830381600087803b15801561202b57600080fd5b505af115801561203f573d6000803e3d6000fd5b505050505b856001600160a01b03166324c1af44868f338f8f8f886040518863ffffffff1660e01b815260040161207c9796959493929190612dd0565b600060405180830381600087803b15801561209657600080fd5b505af11580156120aa573d6000803e3d6000fd5b505050507fe6c19a4d1d5866707f1228c93b673e2667e91ebff83e76dddee75353e938bb028d86338a8c6040516120e5959493929190613026565b60405180910390a150505050505050505050505050565b60015460405163a40b1ee160e01b8152600481018690523360248201526000916001600160a01b03169063a40b1ee1906044016101c060405180830381865afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121719190612e9d565b606081018590526080810184905260a08101839052600154604051633deeb14f60e11b81529192506001600160a01b031690637bdd629e906109a9908890339086906004016130d3565b60006121c6866109e2565b9050600081606001511180156121e0575042816060015111155b61221b5760405162461bcd60e51b815260206004820152600c60248201526b4e6f7420666f722073616c6560a01b6044820152606401610856565b600087511161223c5760405162461bcd60e51b8152600401610856906130ae565b60006122478761166d565b6001546040516331c7c7cf60e21b8152600481018390523360248201529192506000916001600160a01b039091169063c71f1f3c90604401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c09190612f25565b90508363ffffffff16811061230d5760405162461bcd60e51b81526020600482015260136024820152721059191c995cdcc81a185cc818db185a5b5959606a1b6044820152606401610856565b600061231d846080015160281c90565b905061ffff8116158061234b575060008863ffffffff1611801561234b57508061ffff168863ffffffff1611155b61238d5760405162461bcd60e51b815260206004820152601360248201527222bc31b2b2b21026b0bc10223ab930ba34b7b760691b6044820152606401610856565b60006123a3858b61239d8e611140565b8c6125f9565b90508034146123c45760405162461bcd60e51b815260040161085690612f7e565b6040516bffffffffffffffffffffffff193360601b1660208201526001600160e01b031960e088901b16603482015260009060380160405160208183030381529060405280519060200120905061245289898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050505060a088015183612689565b61248e5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610856565b600180546001600160a01b03169063ae25e92a90879033906124b190899061309b565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b0390911660248301526044820152606401600060405180830381600087803b1580156124ff57600080fd5b505af1158015612513573d6000803e3d6000fd5b50505050505050505050505050505050565b60405163d37029ff60e01b81526004810183905260009081906001600160a01b0384169063d37029ff906024016040805180830381865afa15801561256e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125929190612cd9565b90925090506001600160a01b03821615806125b5575042816001600160401b0316105b611d4b5760405162461bcd60e51b81526020600482015260156024820152745375626e6f6465206e6f7420617661696c61626c6560581b6044820152606401610856565b60008061260a866080015185610ce9565b905060648160ff1611156126505760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420617661696c61626c6560981b6044820152606401610856565b606461265c8282613119565b60ff1661266b88888888611c01565b6126759190612f67565b61267f91906130f7565b9695505050505050565b600082612696858461269f565b14949350505050565b600081815b84518110156126e4576126d0828683815181106126c3576126c3613085565b60200260200101516126ec565b9150806126dc8161306c565b9150506126a4565b509392505050565b6000818310612708576000828152602084905260409020610ce2565b6000838152602083905260409020610ce2565b6040518060c001604052806000815260200161273561275d565b815260200161274261275d565b81526000602082018190526040820181905260609091015290565b6040518060a001604052806005906020820280368337509192915050565b6001600160a01b038116811461142b57600080fd5b600080604083850312156127a357600080fd5b8235915060208301356127b58161277b565b809150509250929050565b6000602082840312156127d257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261280057600080fd5b81356001600160401b038082111561281a5761281a6127d9565b604051601f8301601f19908116603f01168101908282118183101715612842576128426127d9565b8160405283815286602085880101111561285b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561288e57600080fd5b82356001600160401b038111156128a457600080fd5b6128b0858286016127ef565b95602094909401359450505050565b8060005b6005811015611d4b5781518452602093840193909101906001016128c3565b8051825260208101516128f860208401826128bf565b50604081015161290b60c08401826128bf565b506060810151610160830152608081015161018083015260a001516101a090910152565b6101c08101610b8f82846128e2565b803563ffffffff8116811461295257600080fd5b919050565b6000806040838503121561296a57600080fd5b8235915061297a6020840161293e565b90509250929050565b6000806040838503121561299657600080fd5b82356129a18161277b565b915060208301356127b58161277b565b8060a08101831015610b8f57600080fd5b60008060008061018085870312156129d957600080fd5b84359350602085013592506129f186604087016129b1565b9150612a008660e087016129b1565b905092959194509250565b60008060408385031215612a1e57600080fd5b50508035926020909101359150565b600080600060608486031215612a4257600080fd5b83356001600160401b03811115612a5857600080fd5b612a64868287016127ef565b93505060208401359150612a7a6040850161293e565b90509250925092565b6001600160401b038116811461142b57600080fd5b803561295281612a83565b60008060008060008060c08789031215612abc57600080fd5b86356001600160401b03811115612ad257600080fd5b612ade89828a016127ef565b965050602087013594506040870135612af68161277b565b93506060870135612b0681612a83565b9250612b146080880161293e565b9150612b2260a0880161293e565b90509295509295509295565b600060208284031215612b4057600080fd5b81356001600160401b03811115612b5657600080fd5b610b77848285016127ef565b60008060008060808587031215612b7857600080fd5b5050823594602084013594506040840135936060013592509050565b6000808284036101e0811215612ba957600080fd5b833592506101c0601f1982011215612bc057600080fd5b506020830190509250929050565b60008060008060008060008060e0898b031215612bea57600080fd5b88356001600160401b0380821115612c0157600080fd5b612c0d8c838d016127ef565b995060208b0135985060408b01359150612c268261277b565b90965060608a013590612c3882612a83565b819650612c4760808c0161293e565b955060a08b0135915080821115612c5d57600080fd5b818b0191508b601f830112612c7157600080fd5b813581811115612c8057600080fd5b8c60208260051b8501011115612c9557600080fd5b602083019550809450505050612cad60c08a01612a98565b90509295985092959890939650565b600060208284031215612cce57600080fd5b8135610ce28161277b565b60008060408385031215612cec57600080fd5b8251612cf78161277b565b60208401519092506127b581612a83565b600060208284031215612d1a57600080fd5b81518015158114610ce257600080fd5b6020808252600c908201526b155b985d5d1a1bdc9a5cd95960a21b604082015260600190565b600060208284031215612d6257600080fd5b8151610ce28161277b565b600060208284031215612d7f57600080fd5b8151610ce281612a83565b6000815180845260005b81811015612db057602081850181015186830182015201612d94565b506000602082860101526020601f19601f83011685010191505092915050565b87815260e060208201526000612de960e0830189612d8a565b6001600160a01b0397881660408401529590961660608201526001600160401b03938416608082015263ffffffff9290921660a083015290911660c0909101529392505050565b600082601f830112612e4157600080fd5b60405160a081018181106001600160401b0382111715612e6357612e636127d9565b6040528060a0840185811115612e7857600080fd5b845b81811015612e92578051835260209283019201612e7a565b509195945050505050565b60006101c08284031215612eb057600080fd5b60405160c081018181106001600160401b0382111715612ed257612ed26127d9565b60405282518152612ee68460208501612e30565b6020820152612ef88460c08501612e30565b6040820152610160830151606082015261018083015160808201526101a09092015160a083015250919050565b600060208284031215612f3757600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610b8f57610b8f612f3e565b8082028115828204841417610b8f57610b8f612f3e565b6020808252600d908201526c496e76616c696420707269636560981b604082015260600190565b63ffffffff818116838216028082169190828114612fc557612fc5612f3e565b505092915050565b6001600160401b03818116838216019080821115612fed57612fed612f3e565b5092915050565b83815260606020820152600061300d6060830185612d8a565b90506001600160401b0383166040830152949350505050565b60a08152600061303960a0830188612d8a565b6020830196909652506001600160a01b0393909316604084015263ffffffff919091166060830152608090910152919050565b60006001820161307e5761307e612f3e565b5060010190565b634e487b7160e01b600052603260045260246000fd5b80820180821115610b8f57610b8f612f3e565b6020808252600b908201526a115b5c1d1e481b1858995b60aa1b604082015260600190565b8381526001600160a01b03831660208201526102008101610b7760408301846128e2565b60008261311457634e487b7160e01b600052601260045260246000fd5b500490565b60ff8281168282160390811115610b8f57610b8f612f3e56fea2646970667358221220a037b31ec1e705082799c5c6fd1e2cbeede0b4078a202915acb97fbfda67372164736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000031694f04e8e68c440cd4287ec147a566f038a14d000000000000000000000000febb6ff64cce7d26ad63194c338cb34eed628a6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85000000000000000000000000178bc6e45cab61e886cbd665f77dbd9615b0d70c

-----Decoded View---------------
Arg [0] : _daoHallRegistry (address): 0x31694F04E8e68c440CD4287EC147a566f038a14d
Arg [1] : _ensController (address): 0xfEBb6ff64cCE7d26Ad63194C338CB34eeD628A6f
Arg [2] : _wrapperController (address): 0x0000000000000000000000000000000000000000
Arg [3] : _wrapper (address): 0x0000000000000000000000000000000000000000
Arg [4] : _ens (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Arg [5] : _registrar (address): 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
Arg [6] : _feeReceiver (address): 0x178BC6e45Cab61E886cBd665F77Dbd9615b0D70C

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 00000000000000000000000031694f04e8e68c440cd4287ec147a566f038a14d
Arg [1] : 000000000000000000000000febb6ff64cce7d26ad63194c338cb34eed628a6f
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Arg [5] : 00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85
Arg [6] : 000000000000000000000000178bc6e45cab61e886cbd665f77dbd9615b0d70c


Deployed Bytecode Sourcemap

44530:13892:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57006:128;;;;;;;;;;-1:-1:-1;57006:128:0;;;;;:::i;:::-;;:::i;:::-;;57140:96;;;;;;;;;;-1:-1:-1;57140:96:0;;;;;:::i;:::-;-1:-1:-1;;;;;57209:21:0;;57140:96;;;;801:25:1;;;789:2;774:18;57140:96:0;;;;;;;;51949:425;;;;;;;;;;-1:-1:-1;51949:425:0;;;;;:::i;:::-;;:::i;48981:292::-;;;;;;;;;;-1:-1:-1;48981:292:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;44909:41::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3555:32:1;;;3537:51;;3525:2;3510:18;44909:41:0;3369:225:1;57471:124:0;;;;;;;;;;-1:-1:-1;57471:124:0;;;;;:::i;:::-;;:::i;:::-;;;4189:14:1;;4182:22;4164:41;;4152:2;4137:18;57471:124:0;4024:187:1;45780:181:0;;;;;;;;;;-1:-1:-1;45780:181:0;;;;;:::i;:::-;;:::i;57242:111::-;;;;;;;;;;-1:-1:-1;57242:111:0;;;;;:::i;:::-;;:::i;44880:24::-;;;;;;;;;;;;;;;47904:292;;;;;;;;;;-1:-1:-1;47904:292:0;;;;;:::i;:::-;;:::i;44712:39::-;;;;;;;;;;-1:-1:-1;44712:39:0;;;;-1:-1:-1;;;;;44712:39:0;;;44756;;;;;;;;;;-1:-1:-1;44756:39:0;;;;-1:-1:-1;;;;;44756:39:0;;;33845:103;;;;;;;;;;;;;:::i;57787:114::-;;;;;;;;;;-1:-1:-1;57787:114:0;;;;;:::i;:::-;57891:2;57881:13;;57787:114;;;;6179:6:1;6167:19;;;6149:38;;6137:2;6122:18;57787:114:0;6005:188:1;49279:156:0;;;;;;;;;;-1:-1:-1;49279:156:0;;;;;:::i;:::-;;:::i;57601:180::-;;;;;;;;;;-1:-1:-1;57601:180:0;;;;;:::i;:::-;;:::i;:::-;;;6943:4:1;6931:17;;;6913:36;;6901:2;6886:18;57601:180:0;6771:184:1;33197:87:0;;;;;;;;;;-1:-1:-1;33243:7:0;33270:6;-1:-1:-1;;;;;33270:6:0;33197:87;;50450:1203;;;;;;:::i;:::-;;:::i;44955:37::-;;;;;;;;;;;;;;;;;;7809:10:1;7797:23;;;7779:42;;7767:2;7752:18;44955:37:0;7635:192:1;48829:146:0;;;;;;;;;;-1:-1:-1;48829:146:0;;;;;:::i;:::-;;:::i;49804:263::-;;;;;;:::i;:::-;;:::i;57907:512::-;;;;;;;;;;-1:-1:-1;57907:512:0;;;;;:::i;:::-;;:::i;44848:27::-;;;;;;;;;;-1:-1:-1;44848:27:0;;;;-1:-1:-1;;;;;44848:27:0;;;44997:26;;;;;;;;;;-1:-1:-1;44997:26:0;;;;-1:-1:-1;;;;;44997:26:0;;;51659:284;;;;;;;;;;-1:-1:-1;51659:284:0;;;;;:::i;:::-;;:::i;48202:256::-;;;;;;;;;;-1:-1:-1;48202:256:0;;;;;:::i;:::-;;:::i;49640:158::-;;;;;;;;;;-1:-1:-1;49640:158:0;;;;;:::i;:::-;;:::i;44800:43::-;;;;;;;;;;-1:-1:-1;44800:43:0;;;;-1:-1:-1;;;;;44800:43:0;;;48464:359;;;;;;;;;;-1:-1:-1;48464:359:0;;;;;:::i;:::-;;:::i;50073:371::-;;;;;;:::i;:::-;;:::i;56896:104::-;;;;;;;;;;-1:-1:-1;56896:104:0;;;;;:::i;:::-;;:::i;34103:201::-;;;;;;;;;;-1:-1:-1;34103:201:0;;;;;:::i;:::-;;:::i;57359:106::-;;;;;;;;;;-1:-1:-1;57359:106:0;;;;;:::i;:::-;;:::i;49441:193::-;;;;;;;;;;-1:-1:-1;49441:193:0;;;;;:::i;:::-;;:::i;57006:128::-;33083:13;:11;:13::i;:::-;57084:44:::1;57110:8;57121:6;57084:17;:44::i;:::-;57006:128:::0;;:::o;51949:425::-;52027:12;52042:46;52052:10;52080:5;52064:23;;;;;;56728:33;;;;;;;22470:19:1;;;;22505:12;;;22498:28;;;;56728:33:0;;;;;;;;;22542:12:1;;;;56728:33:0;;56718:44;;;;;;56622:146;52042:46;52128:13;;:31;;-1:-1:-1;;;52128:31:0;;;;;801:25:1;;;52027:61:0;;-1:-1:-1;52096:13:0;;;;-1:-1:-1;;;;;52128:13:0;;:25;;774:18:1;;52128:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52095:64;;-1:-1:-1;52095:64:0;-1:-1:-1;;;;;;52174:19:0;;52183:10;52174:19;;:62;;-1:-1:-1;52197:39:0;;-1:-1:-1;;;52197:39:0;;-1:-1:-1;;;;;12570:15:1;;;52197:39:0;;;12552:34:1;52225:10:0;12602:18:1;;;12595:43;52197:3:0;:20;;;;12487:18:1;;52197:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52166:87;;;;-1:-1:-1;;;52166:87:0;;;;;;;:::i;:::-;;;;;;;;;52262:17;;52323:18;;-1:-1:-1;;;52323:18:0;;;;;801:25:1;;;-1:-1:-1;;;;;52262:17:0;;;;:34;;52297:10;;52309:5;;52316;;52323:3;:12;;;;774:18:1;;52323::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52343:13;;-1:-1:-1;;;52343:13:0;;;;;801:25:1;;;52343:3:0;-1:-1:-1;;;;;52343:7:0;;;;774:18:1;;52343:13:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52358:1;52361:6;52262:106;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52020:354;;;51949:425;;:::o;48981:292::-;49040:17;;:::i;:::-;49066:12;49081:18;49089:9;49081:7;:18::i;:::-;49066:33;;49106:13;49122:20;49132:9;49122;:20::i;:::-;:93;;49178:37;;-1:-1:-1;;;49178:37:0;;;;;801:25:1;;;49178:9:0;-1:-1:-1;;;;;49178:17:0;;;;774:18:1;;49178:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49122:93;;;49145:7;;;:30;;-1:-1:-1;;;49145:30:0;;;;;801:25:1;;;-1:-1:-1;;;;;49145:7:0;;:15;;774:18:1;;49145:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49229:15;;:38;;-1:-1:-1;;;49229:38:0;;;;;15171:25:1;;;-1:-1:-1;;;;;15232:32:1;;;15212:18;;;15205:60;49106:109:0;;-1:-1:-1;49229:15:0;;;:25;;15144:18:1;;49229:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49222:45;48981:292;-1:-1:-1;;;;48981:292:0:o;57471:124::-;57556:33;57573:3;57564:12;;;57557:27;;57556:33;;;57471:124;;;;;:::o;45780:181::-;33083:13;:11;:13::i;:::-;45892:7:::1;:18:::0;;-1:-1:-1;;;;;45892:18:0;;::::1;-1:-1:-1::0;;;;;;45892:18:0;;::::1;;::::0;;;45917:17:::1;:38:::0;;;;;::::1;::::0;::::1;;::::0;;45780:181::o;57242:111::-;57298:4;57317:30;57325:5;44346:1;57317:7;:30::i;47904:292::-;48043:9;46090:36;46104:9;46115:10;46090:13;:36::i;:::-;46082:61;;;;-1:-1:-1;;;46082:61:0;;;;;;;:::i;:::-;48060:12:::1;48075:18;48083:9;48075:7;:18::i;:::-;48060:33;;48100:49;48110:4;48116:9;48127:11;48140:8;48100:9;:49::i;:::-;48161:29;::::0;;15171:25:1;;;48179:10:0::1;15227:2:1::0;15212:18;;15205:60;48161:29:0::1;::::0;15144:18:1;48161:29:0::1;;;;;;;48053:143;47904:292:::0;;;;;:::o;33845:103::-;33083:13;:11;:13::i;:::-;33910:30:::1;33937:1;33910:18;:30::i;:::-;33845:103::o:0;49279:156::-;49379:15;;:50;;-1:-1:-1;;;49379:50:0;;;;;15171:25:1;;;-1:-1:-1;;;;;15232:32:1;;;15212:18;;;15205:60;49357:7:0;;49379:15;;:35;;15144:18:1;;49379:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49372:57;49279:156;-1:-1:-1;;;49279:156:0:o;57601:180::-;57680:5;57693:13;57718:1;57709:6;:10;:27;;57726:10;57735:1;57726:6;:10;:::i;:::-;57709:27;;;57722:1;57709:27;57693:43;-1:-1:-1;57766:7:0;57693:43;57772:1;57766:7;:::i;:::-;57756:18;;;;;57601:180;-1:-1:-1;;;57601:180:0:o;50450:1203::-;50555:29;50587:24;50600:10;50587:12;:24::i;:::-;50555:56;;50644:18;50665:19;50673:10;50665:7;:19::i;:::-;50644:40;;50691:12;50706:46;50716:10;50744:5;50728:23;;;;;;56728:33;;;;;;;22470:19:1;;;;22505:12;;;22498:28;;;;56728:33:0;;;;;;;;;22542:12:1;;;;56728:33:0;;56718:44;;;;;;56622:146;50706:46;50691:61;;50760:13;50775:16;50795:10;-1:-1:-1;;;;;50795:22:0;;50818:4;50795:28;;;;;;;;;;;;;801:25:1;;789:2;774:18;;655:177;50795:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50759:64;;-1:-1:-1;50759:64:0;-1:-1:-1;;;;;;50838:19:0;;50830:47;;;;-1:-1:-1;;;50830:47:0;;17597:2:1;50830:47:0;;;17579:21:1;17636:2;17616:18;;;17609:30;-1:-1:-1;;;17655:18:1;;;17648:45;17710:18;;50830:47:0;17395:339:1;50830:47:0;50931:34;;-1:-1:-1;;;50931:34:0;;;;;801:25:1;;;50887:19:0;;;;-1:-1:-1;;;;;50931:22:0;;;;;774:18:1;;50931:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50999:15;;:50;;-1:-1:-1;;;50999:50:0;;;;;15171:25:1;;;-1:-1:-1;;;;;15232:32:1;;;15212:18;;;15205:60;50886:79:0;;-1:-1:-1;50886:79:0;;-1:-1:-1;50972:24:0;;50999:15;;:25;;15144:18:1;;50999:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50972:77;;51062:37;51076:10;51088;51062:13;:37::i;:::-;51058:165;;51130:67;51146:6;51154:10;51166:20;51180:5;51166:13;:20::i;:::-;51188:8;51130:15;:67::i;:::-;51117:9;:80;51109:106;;;;-1:-1:-1;;;51109:106:0;;;;;;;:::i;:::-;51250:12;51276;;;;51273:149;;51330:19;:8;51341;51330:19;:::i;:::-;51317:33;;;;:9;:33;:::i;:::-;51298:53;;51381:12;-1:-1:-1;;;;;51368:25:0;:9;-1:-1:-1;;;;;51368:25:0;;;51360:54;;;;-1:-1:-1;;;51360:54:0;;18722:2:1;51360:54:0;;;18704:21:1;18761:2;18741:18;;;18734:30;-1:-1:-1;;;18780:18:1;;;18773:46;18836:18;;51360:54:0;18520:340:1;51360:54:0;51433:9;:13;51430:69;;51456:35;51468:9;51479:11;51456;:35::i;:::-;51511:10;-1:-1:-1;;;;;51511:27:0;;51539:10;51551:5;51558:9;51511:57;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51580:67;51596:5;51603:10;51615;51627:8;51637:9;51580:67;;;;;;;;;;:::i;:::-;;;;;;;;50548:1105;;;;;;;;;50450:1203;;;:::o;48829:146::-;48898:17;;:::i;:::-;48931:15;;:38;;-1:-1:-1;;;48931:38:0;;;;;15171:25:1;;;-1:-1:-1;;;;;15232:32:1;;;15212:18;;;15205:60;48931:15:0;;;;:25;;15144:18:1;;48931:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;49804:263::-;49950:38;49960:5;49967:10;49979:8;49950:9;:38::i;:::-;49995:66;50000:5;50007:10;50019:8;50029:3;50034:5;50041:9;50052:8;49995:4;:66::i;:::-;49804:263;;;;;;:::o;57907:512::-;58034:9;;57970:7;;58009:3;;57970:7;;58095:299;58105:3;58101:1;:7;58095:299;;;58120:9;;;;:::i;:::-;;;;58140:8;58157:2;58160:1;58157:5;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;58182:4:0;58177:9;;58174:213;;;58202:4;;;;:::i;:::-;;;;58174:213;;;58241:4;58236:2;:9;;;58233:154;;;58261:6;58266:1;58261:6;;:::i;:::-;;;58233:154;;;58302:4;58297:2;:9;;;58294:93;;;58322:6;58327:1;58322:6;;:::i;58294:93::-;58369:6;58374:1;58369:6;;:::i;:::-;;;58294:93;58109:285;58095:299;;;58407:6;57907:512;-1:-1:-1;;;;;57907:512:0:o;51659:284::-;51806:10;46090:36;46104:9;46115:10;46090:13;:36::i;:::-;46082:61;;;;-1:-1:-1;;;46082:61:0;;;;;;;:::i;:::-;51855:1:::1;51832:20;51846:5;51832:13;:20::i;:::-;:24;51824:48;;;;-1:-1:-1::0;;;51824:48:0::1;;;;;;;:::i;:::-;51879:58;51884:5;51891:10;51903:8;51913:3;51918:5;51925:1;51928:8;51879:4;:58::i;:::-;51659:284:::0;;;;;;;:::o;48202:256::-;48311:9;46090:36;46104:9;46115:10;46090:13;:36::i;:::-;46082:61;;;;-1:-1:-1;;;46082:61:0;;;;;;;:::i;:::-;48328:12:::1;48343:18;48351:9;48343:7;:18::i;:::-;48328:33;;48368:43;48382:4;48388:9;48399:5;48406:4;48368:13;:43::i;49640:158::-:0;49702:18;49736:20;49746:9;49736;:20::i;:::-;:56;;49779:13;;-1:-1:-1;;;;;49779:13:0;49736:56;;;-1:-1:-1;;49759:17:0;;-1:-1:-1;;;;;49759:17:0;;49640:158::o;48464:359::-;48550:9;46090:36;46104:9;46115:10;46090:13;:36::i;:::-;46082:61;;;;-1:-1:-1;;;46082:61:0;;;;;;;:::i;:::-;48568:12:::1;48583:18;48591:9;48583:7;:18::i;:::-;48568:33:::0;-1:-1:-1;48608:70:0::1;48568:33:::0;48624:16;::::1;48642:18;::::0;::::1;48662:15;::::0;::::1;48608:9;:70::i;:::-;48685:91;48699:4;48705:6;:25;;;48732:6;:21;;;48755:6;:20;;;48685:13;:91::i;:::-;48788:29;::::0;;15171:25:1;;;48806:10:0::1;15227:2:1::0;15212:18;;15205:60;48788:29:0::1;::::0;15144:18:1;48788:29:0::1;;;;;;;48561:262;48464:359:::0;;;:::o;50073:371::-;50277:4;50289:76;50310:5;50317:10;50277:4;50339:5;;50353:10;50361:2;50353:10;;;;50289:20;:76::i;:::-;50372:66;50377:5;50384:10;50396:8;50406:3;50411:5;50418:9;50429:8;50372:4;:66::i;56896:104::-;33083:13;:11;:13::i;:::-;56968:11:::1;:26:::0;;-1:-1:-1;;;;;;56968:26:0::1;-1:-1:-1::0;;;;;56968:26:0;;;::::1;::::0;;;::::1;::::0;;56896:104::o;34103:201::-;33083:13;:11;:13::i;:::-;-1:-1:-1;;;;;34192:22:0;::::1;34184:73;;;::::0;-1:-1:-1;;;34184:73:0;;20752:2:1;34184:73:0::1;::::0;::::1;20734:21:1::0;20791:2;20771:18;;;20764:30;20830:34;20810:18;;;20803:62;-1:-1:-1;;;20881:18:1;;;20874:36;20927:19;;34184:73:0::1;20550:402:1::0;34184:73:0::1;34268:28;34287:8;34268:18;:28::i;:::-;34103:201:::0;:::o;57359:106::-;57413:4;57432:27;57440:5;44380:1;57432:7;:27::i;49441:193::-;49529:37;;-1:-1:-1;;;49529:37:0;;;;;801:25:1;;;49500:4:0;;;;49529:9;-1:-1:-1;;;;;49529:17:0;;;;774:18:1;;49529:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49513:53;-1:-1:-1;;;;;;49580:19:0;;;;;;:48;;-1:-1:-1;49620:7:0;;-1:-1:-1;;;;;49620:7:0;;;49603:25;;;;49573:55;-1:-1:-1;;49441:193:0:o;33362:132::-;33243:7;33270:6;-1:-1:-1;;;;;33270:6:0;31822:10;33426:23;33418:68;;;;-1:-1:-1;;;33418:68:0;;21159:2:1;33418:68:0;;;21141:21:1;;;21178:18;;;21171:30;21237:34;21217:18;;;21210:62;21289:18;;33418:68:0;20957:356:1;24121:317:0;24236:6;24211:21;:31;;24203:73;;;;-1:-1:-1;;;24203:73:0;;21520:2:1;24203:73:0;;;21502:21:1;21559:2;21539:18;;;21532:30;21598:31;21578:18;;;21571:59;21647:18;;24203:73:0;21318:353:1;24203:73:0;24290:12;24308:9;-1:-1:-1;;;;;24308:14:0;24330:6;24308:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24289:52;;;24360:7;24352:78;;;;-1:-1:-1;;;24352:78:0;;22088:2:1;24352:78:0;;;22070:21:1;22127:2;22107:18;;;22100:30;22166:34;22146:18;;;22139:62;22237:28;22217:18;;;22210:56;22283:19;;24352:78:0;21886:422:1;24352:78:0;24192:246;24121:317;;:::o;56774:116::-;56728:33;;;44639:66;56728:33;;;;22470:19:1;;;;22505:12;;;22498:28;;;56728:33:0;;;;;;;;;22542:12:1;;;;56728:33:0;;;56718:44;;;;;56832:7;;56854:30;56622:146;46163:440;46246:4;46262:20;46272:9;46262;:20::i;:::-;46259:339;;;46308:7;;46292:13;;-1:-1:-1;;;;;46308:7:0;:15;46332:18;46340:9;46332:7;:18::i;:::-;46308:44;;;;;;-1:-1:-1;;;;;;46308:44:0;;;;;;801:25:1;;;;774:18;;46308:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46292:60;;46377:8;-1:-1:-1;;;;;46368:17:0;:5;-1:-1:-1;;;;;46368:17:0;;:62;;;-1:-1:-1;46389:7:0;;;:41;;-1:-1:-1;;;46389:41:0;;-1:-1:-1;;;;;12570:15:1;;;46389:41:0;;;12552:34:1;;;;12622:15;;;12602:18;;;12595:43;46389:7:0;;;:24;;12487:18:1;;46389:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46361:69;;;;;46259:339;46473:37;;-1:-1:-1;;;46473:37:0;;;;;801:25:1;;;46457:13:0;;46473:9;-1:-1:-1;;;;;46473:17:0;;;;774:18:1;;46473:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46457:53;;46535:8;-1:-1:-1;;;;;46526:17:0;:5;-1:-1:-1;;;;;46526:17:0;;:64;;;-1:-1:-1;46547:43:0;;-1:-1:-1;;;46547:43:0;;-1:-1:-1;;;;;12570:15:1;;;46547:43:0;;;12552:34:1;12622:15;;;12602:18;;;12595:43;46547:9:0;:26;;;;12487:18:1;;46547:43:0;12340:304:1;46609:935:0;46766:15;;:43;;-1:-1:-1;;;46766:43:0;;;;;15171:25:1;;;46798:10:0;15212:18:1;;;15205:60;46739:24:0;;-1:-1:-1;;;;;46766:15:0;;:25;;15144:18:1;;46766:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46816:28;;;46739:70;-1:-1:-1;46816:16:0;46851:630;46871:1;46867;:5;46851:630;;;46891:31;46900:6;:18;;;46919:1;46900:21;;;;;;;:::i;:::-;;;;;46891:8;:31::i;:::-;46888:232;;;46988:11;47000:1;46988:14;;;;;;;:::i;:::-;;;;;46963:6;:18;;;46982:1;46963:21;;;;;;;:::i;:::-;;;;;:39;;:76;;;;47028:8;47037:1;47028:11;;;;;;;:::i;:::-;;;;;47006:6;:15;;;47022:1;47006:18;;;;;;;:::i;:::-;;;;;:33;;46963:76;46960:132;;;47060:20;;-1:-1:-1;;;47060:20:0;;;;;22739:25:1;;;22780:18;;;22773:34;;;22712:18;;47060:20:0;22565:248:1;46960:132:0;47102:8;;46888:232;47131:34;47143:6;:18;;;47162:1;47143:21;;;;;;;:::i;:::-;;;;;47131:11;:34::i;:::-;:66;;;;;47170:27;47182:11;47194:1;47182:14;;;;;;;:::i;:::-;;;;;47170:11;:27::i;:::-;47169:28;47131:66;47128:128;;;47216:30;;-1:-1:-1;;;47216:30:0;;;;;22739:25:1;;;22780:18;;;22773:34;;;22712:18;;47216:30:0;22565:248:1;47128:128:0;47267:31;47279:6;:15;;;47295:1;47279:18;;;;;;;:::i;47267:31::-;:60;;;;;47303:24;47315:8;47324:1;47315:11;;;;;;;:::i;47303:24::-;47302:25;47267:60;47264:122;;;47346:30;;-1:-1:-1;;;47346:30:0;;;;;22739:25:1;;;22780:18;;;22773:34;;;22712:18;;47346:30:0;22565:248:1;47264:122:0;47418:11;47430:1;47418:14;;;;;;;:::i;:::-;;;;;47394:6;:18;;;47413:1;47394:21;;;;;;;:::i;:::-;;;;:38;47462:8;47471:1;47462:11;;;;;;;:::i;:::-;;;;;47441:6;:15;;;47457:1;47441:18;;;;;;;:::i;:::-;;;;:32;46851:630;46874:4;;;;:::i;:::-;;;;46851:630;;;-1:-1:-1;47487:15:0;;:51;;-1:-1:-1;;;47487:51:0;;-1:-1:-1;;;;;47487:15:0;;;;:25;;:51;;47513:4;;47519:10;;47531:6;;47487:51;;;:::i;34464:191::-;34538:16;34557:6;;-1:-1:-1;;;;;34574:17:0;;;-1:-1:-1;;;;;;34574:17:0;;;;;;34607:40;;34557:6;;;;;;;34607:40;;34538:16;34607:40;34527:128;34464:191;:::o;52380:462::-;52507:7;52523:13;52548:1;52539:6;:10;:27;;52556:10;52565:1;52556:6;:10;:::i;:::-;52539:27;;;52552:1;52539:27;52523:43;-1:-1:-1;52573:13:0;52589;;;;:66;;52630:6;:18;;;52649:5;52630:25;;;;;;;:::i;:::-;;;;;52589:66;;;52605:6;:15;;;52621:5;52605:22;;;;;;;:::i;:::-;;;;;52589:66;52573:82;;52666:18;52678:5;52666:11;:18::i;:::-;52662:92;;52719:19;52727:10;52719:7;:19::i;:::-;52701:45;;-1:-1:-1;;;52701:45:0;;;;;22739:25:1;;;;22780:18;;;22773:34;;;22712:18;;52701:45:0;22565:248:1;52662:92:0;-1:-1:-1;;;;;57209:21:0;52797:12;;;:39;;52831:5;52797:39;;;52812:16;;;;:5;:16;:::i;:::-;52790:46;52380:462;-1:-1:-1;;;;;;;52380:462:0:o;56372:244::-;56439:11;56471:5;56453:15;;56461:7;56453:15;:5;:15;:::i;:::-;:23;;;;:::i;:::-;56439:37;-1:-1:-1;56483:14:0;56500:11;56439:37;56500:5;:11;:::i;:::-;56483:28;;56518:41;56544:5;56552:6;56518:17;:41::i;:::-;56592:11;;56566:44;;-1:-1:-1;;;;;56592:11:0;56606:3;56566:17;:44::i;:::-;56432:184;;56372:244;;:::o;53242:468::-;53335:24;53362:21;53372:10;53362:9;:21::i;:::-;53398:16;;53335:48;;-1:-1:-1;53398:20:0;;;;:59;;-1:-1:-1;53422:16:0;;53442:15;-1:-1:-1;53422:35:0;53398:59;53390:84;;;;-1:-1:-1;;;53390:84:0;;23667:2:1;53390:84:0;;;23649:21:1;23706:2;23686:18;;;23679:30;-1:-1:-1;;;23725:18:1;;;23718:42;23777:18;;53390:84:0;23465:336:1;53390:84:0;53481:11;53495:20;53509:5;53495:13;:20::i;:::-;53481:34;;53536:1;53530:3;:7;53522:31;;;;-1:-1:-1;;;53522:31:0;;;;;;;:::i;:::-;53587:13;53603:50;53619:6;53627:10;53639:3;53644:8;53603:15;:50::i;:::-;53587:66;;53681:5;53668:9;:18;53660:44;;;;-1:-1:-1;;;53660:44:0;;;;;;;:::i;55121:1245::-;55267:29;55299:24;55312:10;55299:12;:24::i;:::-;55267:56;;55330:18;55351:19;55359:10;55351:7;:19::i;:::-;55330:40;;55377:12;55392:46;55402:10;55430:5;55414:23;;;;;;56728:33;;;;;;;22470:19:1;;;;22505:12;;;22498:28;;;;56728:33:0;;;;;;;;;22542:12:1;;;;56728:33:0;;56718:44;;;;;;56622:146;55392:46;55377:61;;55472:36;55491:4;55497:10;55472:18;:36::i;:::-;55588:34;;-1:-1:-1;;;55588:34:0;;;;;801:25:1;;;55544:19:0;;;;-1:-1:-1;;;;;55588:22:0;;;;;774:18:1;;55588:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55543:79;;-1:-1:-1;55543:79:0;-1:-1:-1;55543:79:0;55672:12;;;;55669:159;;55734:19;:8;55745;55734:19;:::i;:::-;55715:39;;;;:15;:39;:::i;:::-;55694:61;;55787:12;-1:-1:-1;;;;;55772:27:0;:11;-1:-1:-1;;;;;55772:27:0;;;55764:56;;;;-1:-1:-1;;;55764:56:0;;18722:2:1;55764:56:0;;;18704:21:1;18761:2;18741:18;;;18734:30;-1:-1:-1;;;18780:18:1;;;18773:46;18836:18;;55764:56:0;18520:340:1;55764:56:0;55843:9;;55840:61;;55862:31;55874:5;55881:11;55862;:31::i;:::-;-1:-1:-1;;;;;55910:22:0;;;55907:283;;56033:10;-1:-1:-1;;;;;56033:27:0;;56061:10;56073:5;56088:4;56095:8;56105:3;56110:5;56117:11;56033:96;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56138:44:0;;-1:-1:-1;;;56138:44:0;;;;;15171:25:1;;;56171:10:0;15212:18:1;;;15205:60;-1:-1:-1;;;;;56138:26:0;;;-1:-1:-1;56138:26:0;;-1:-1:-1;15144:18:1;;56138:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55907:283;56196:10;-1:-1:-1;;;;;56196:27:0;;56224:10;56236:5;56243:10;56255:8;56265:3;56270:5;56277:11;56196:93;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56301:59;56313:5;56320:10;56332;56344:8;56354:5;56301:59;;;;;;;;;;:::i;:::-;;;;;;;;55260:1106;;;;;;55121:1245;;;;;;;:::o;47550:348::-;47677:15;;:43;;-1:-1:-1;;;47677:43:0;;;;;15171:25:1;;;47709:10:0;15212:18:1;;;15205:60;47650:24:0;;-1:-1:-1;;;;;47677:15:0;;:25;;15144:18:1;;47677:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47727:25;;;:37;;;47771:21;;;:29;;;47807:20;;;:27;;;47841:15;;:51;;-1:-1:-1;;;47841:51:0;;47650:70;;-1:-1:-1;;;;;;47841:15:0;;:25;;:51;;47867:4;;47873:10;;47650:70;;47841:51;;;:::i;53716:1144::-;53860:24;53887:21;53897:10;53887:9;:21::i;:::-;53860:48;;53951:1;53923:6;:25;;;:29;:77;;;;;53985:15;53956:6;:25;;;:44;;53923:77;53915:102;;;;-1:-1:-1;;;53915:102:0;;23667:2:1;53915:102:0;;;23649:21:1;23706:2;23686:18;;;23679:30;-1:-1:-1;;;23725:18:1;;;23718:42;23777:18;;53915:102:0;23465:336:1;53915:102:0;54054:1;54038:5;54032:19;:23;54024:47;;;;-1:-1:-1;;;54024:47:0;;;;;;;:::i;:::-;54080:18;54101:19;54109:10;54101:7;:19::i;:::-;54145:15;;:59;;-1:-1:-1;;;54145:59:0;;;;;15171:25:1;;;54193:10:0;15212:18:1;;;15205:60;54080:40:0;;-1:-1:-1;54127:15:0;;-1:-1:-1;;;;;54145:15:0;;;;:35;;15144:18:1;;54145:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54127:77;;54229:5;54219:15;;:7;:15;54211:47;;;;-1:-1:-1;;;54211:47:0;;24786:2:1;54211:47:0;;;24768:21:1;24825:2;24805:18;;;24798:30;-1:-1:-1;;;24844:18:1;;;24837:49;24903:18;;54211:47:0;24584:343:1;54211:47:0;54267:18;54288:43;54309:6;:21;;;57891:2;57881:13;;57787:114;54288:43;54267:64;-1:-1:-1;54346:16:0;;;;;:61;;;54378:1;54367:8;:12;;;:39;;;;;54395:11;54383:23;;:8;:23;;;;54367:39;54338:93;;;;-1:-1:-1;;;54338:93:0;;25134:2:1;54338:93:0;;;25116:21:1;25173:2;25153:18;;;25146:30;-1:-1:-1;;;25192:18:1;;;25185:49;25251:18;;54338:93:0;24932:343:1;54338:93:0;54465:13;54482:78;54509:6;54517:10;54529:20;54543:5;54529:13;:20::i;:::-;54551:8;54482:26;:78::i;:::-;54465:95;;54588:5;54575:9;:18;54567:44;;;;-1:-1:-1;;;54567:44:0;;;;;;;:::i;:::-;54645:43;;-1:-1:-1;;54662:10:0;25455:2:1;25451:15;25447:53;54645:43:0;;;25435:66:1;-1:-1:-1;;;;;;54674:13:0;;;;25531:33:1;25517:12;;;25510:55;54620:12:0;;25581::1;;54645:43:0;;;;;;;;;;;;54635:54;;;;;;54620:69;;54704:53;54723:5;;54704:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;54730:20:0;;;;54752:4;54704:18;:53::i;:::-;54696:79;;;;-1:-1:-1;;;54696:79:0;;25806:2:1;54696:79:0;;;25788:21:1;25845:2;25825:18;;;25818:30;-1:-1:-1;;;25864:18:1;;;25857:43;25917:18;;54696:79:0;25604:337:1;54696:79:0;54782:15;;;-1:-1:-1;;;;;54782:15:0;;:35;;54818:10;;54830;;54842:11;;:7;;:11;:::i;:::-;54782:72;;-1:-1:-1;;;;;;54782:72:0;;;;;;;;;;26148:25:1;;;;-1:-1:-1;;;;;26209:32:1;;;26189:18;;;26182:60;26258:18;;;26251:34;26121:18;;54782:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53853:1007;;;;;;53716:1144;;;;;;:::o;54866:249::-;54993:28;;-1:-1:-1;;;54993:28:0;;;;;801:25:1;;;54961:13:0;;;;-1:-1:-1;;;;;54993:22:0;;;;;774:18:1;;54993:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54960:61;;-1:-1:-1;54960:61:0;-1:-1:-1;;;;;;55036:19:0;;;;:47;;;55068:15;55059:6;-1:-1:-1;;;;;55059:24:0;;55036:47;55028:81;;;;-1:-1:-1;;;55028:81:0;;26498:2:1;55028:81:0;;;26480:21:1;26537:2;26517:18;;;26510:30;-1:-1:-1;;;26556:18:1;;;26549:51;26617:18;;55028:81:0;26296:345:1;52848:388:0;52986:7;53025:14;53042:48;53060:6;:21;;;53083:6;53042:17;:48::i;:::-;53025:65;;53117:3;53105:8;:15;;;;53097:41;;;;-1:-1:-1;;;53097:41:0;;26848:2:1;53097:41:0;;;26830:21:1;26887:2;26867:18;;;26860:30;-1:-1:-1;;;26906:18:1;;;26899:43;26959:18;;53097:41:0;26646:337:1;53097:41:0;53227:3;53209:14;53215:8;53227:3;53209:14;:::i;:::-;53152:72;;:53;53168:6;53176:10;53188:6;53196:8;53152:15;:53::i;:::-;:72;;;;:::i;:::-;:78;;;;:::i;:::-;53145:85;52848:388;-1:-1:-1;;;;;;52848:388:0:o;35892:190::-;36017:4;36070;36041:25;36054:5;36061:4;36041:12;:25::i;:::-;:33;;35892:190;-1:-1:-1;;;;35892:190:0:o;36759:296::-;36842:7;36885:4;36842:7;36900:118;36924:5;:12;36920:1;:16;36900:118;;;36973:33;36983:12;36997:5;37003:1;36997:8;;;;;;;;:::i;:::-;;;;;;;36973:9;:33::i;:::-;36958:48;-1:-1:-1;36938:3:0;;;;:::i;:::-;;;;36900:118;;;-1:-1:-1;37035:12:0;36759:296;-1:-1:-1;;;36759:296:0:o;43799:149::-;43862:7;43893:1;43889;:5;:51;;44024:13;44118:15;;;44154:4;44147:15;;;44201:4;44185:21;;43889:51;;;44024:13;44118:15;;;44154:4;44147:15;;;44201:4;44185:21;;43897:20;43956:268;-1:-1:-1;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:315;218:6;226;279:2;267:9;258:7;254:23;250:32;247:52;;;295:1;292;285:12;247:52;331:9;318:23;308:33;;391:2;380:9;376:18;363:32;404:31;429:5;404:31;:::i;:::-;454:5;444:15;;;150:315;;;;;:::o;470:180::-;529:6;582:2;570:9;561:7;557:23;553:32;550:52;;;598:1;595;588:12;550:52;-1:-1:-1;621:23:1;;470:180;-1:-1:-1;470:180:1:o;837:127::-;898:10;893:3;889:20;886:1;879:31;929:4;926:1;919:15;953:4;950:1;943:15;969:719;1012:5;1065:3;1058:4;1050:6;1046:17;1042:27;1032:55;;1083:1;1080;1073:12;1032:55;1119:6;1106:20;-1:-1:-1;;;;;1182:2:1;1178;1175:10;1172:36;;;1188:18;;:::i;:::-;1263:2;1257:9;1231:2;1317:13;;-1:-1:-1;;1313:22:1;;;1337:2;1309:31;1305:40;1293:53;;;1361:18;;;1381:22;;;1358:46;1355:72;;;1407:18;;:::i;:::-;1447:10;1443:2;1436:22;1482:2;1474:6;1467:18;1528:3;1521:4;1516:2;1508:6;1504:15;1500:26;1497:35;1494:55;;;1545:1;1542;1535:12;1494:55;1609:2;1602:4;1594:6;1590:17;1583:4;1575:6;1571:17;1558:54;1656:1;1649:4;1644:2;1636:6;1632:15;1628:26;1621:37;1676:6;1667:15;;;;;;969:719;;;;:::o;1693:390::-;1771:6;1779;1832:2;1820:9;1811:7;1807:23;1803:32;1800:52;;;1848:1;1845;1838:12;1800:52;1888:9;1875:23;-1:-1:-1;;;;;1913:6:1;1910:30;1907:50;;;1953:1;1950;1943:12;1907:50;1976;2018:7;2009:6;1998:9;1994:22;1976:50;:::i;:::-;1966:60;2073:2;2058:18;;;;2045:32;;-1:-1:-1;;;;1693:390:1:o;2273:326::-;2366:5;2389:1;2399:194;2413:4;2410:1;2407:11;2399:194;;;2472:13;;2460:26;;2509:4;2533:12;;;;2568:15;;;;2433:1;2426:9;2399:194;;2604:503;2686:5;2680:12;2675:3;2668:25;2739:4;2732:5;2728:16;2722:23;2754:54;2802:4;2797:3;2793:14;2779:12;2754:54;:::i;:::-;;2856:4;2849:5;2845:16;2839:23;2871:56;2921:4;2916:3;2912:14;2896;2871:56;:::i;:::-;-1:-1:-1;2978:4:1;2967:16;;2961:23;2952:6;2943:16;;2936:49;3036:4;3025:16;;3019:23;3010:6;3001:16;;2994:49;3094:4;3083:16;3077:23;3068:6;3059:16;;;3052:49;2604:503::o;3112:252::-;3298:3;3283:19;;3311:47;3287:9;3340:6;3311:47;:::i;3599:163::-;3666:20;;3726:10;3715:22;;3705:33;;3695:61;;3752:1;3749;3742:12;3695:61;3599:163;;;:::o;3767:252::-;3834:6;3842;3895:2;3883:9;3874:7;3870:23;3866:32;3863:52;;;3911:1;3908;3901:12;3863:52;3947:9;3934:23;3924:33;;3976:37;4009:2;3998:9;3994:18;3976:37;:::i;:::-;3966:47;;3767:252;;;;;:::o;4216:434::-;4330:6;4338;4391:2;4379:9;4370:7;4366:23;4362:32;4359:52;;;4407:1;4404;4397:12;4359:52;4446:9;4433:23;4465:31;4490:5;4465:31;:::i;:::-;4515:5;-1:-1:-1;4572:2:1;4557:18;;4544:32;4585:33;4544:32;4585:33;:::i;4874:160::-;4968:6;5001:3;4989:16;;4986:25;-1:-1:-1;4983:45:1;;;5024:1;5021;5014:12;5039:496;5175:6;5183;5191;5199;5252:3;5240:9;5231:7;5227:23;5223:33;5220:53;;;5269:1;5266;5259:12;5220:53;5305:9;5292:23;5282:33;;5362:2;5351:9;5347:18;5334:32;5324:42;;5385:62;5439:7;5434:2;5423:9;5419:18;5385:62;:::i;:::-;5375:72;;5466:63;5521:7;5515:3;5504:9;5500:19;5466:63;:::i;:::-;5456:73;;5039:496;;;;;;;:::o;6518:248::-;6586:6;6594;6647:2;6635:9;6626:7;6622:23;6618:32;6615:52;;;6663:1;6660;6653:12;6615:52;-1:-1:-1;;6686:23:1;;;6756:2;6741:18;;;6728:32;;-1:-1:-1;6518:248:1:o;7168:462::-;7254:6;7262;7270;7323:2;7311:9;7302:7;7298:23;7294:32;7291:52;;;7339:1;7336;7329:12;7291:52;7379:9;7366:23;-1:-1:-1;;;;;7404:6:1;7401:30;7398:50;;;7444:1;7441;7434:12;7398:50;7467;7509:7;7500:6;7489:9;7485:22;7467:50;:::i;:::-;7457:60;;;7564:2;7553:9;7549:18;7536:32;7526:42;;7587:37;7620:2;7609:9;7605:18;7587:37;:::i;:::-;7577:47;;7168:462;;;;;:::o;7832:129::-;-1:-1:-1;;;;;7910:5:1;7906:30;7899:5;7896:41;7886:69;;7951:1;7948;7941:12;7966:132;8033:20;;8062:30;8033:20;8062:30;:::i;8103:811::-;8214:6;8222;8230;8238;8246;8254;8307:3;8295:9;8286:7;8282:23;8278:33;8275:53;;;8324:1;8321;8314:12;8275:53;8364:9;8351:23;-1:-1:-1;;;;;8389:6:1;8386:30;8383:50;;;8429:1;8426;8419:12;8383:50;8452;8494:7;8485:6;8474:9;8470:22;8452:50;:::i;:::-;8442:60;;;8549:2;8538:9;8534:18;8521:32;8511:42;;8603:2;8592:9;8588:18;8575:32;8616:31;8641:5;8616:31;:::i;:::-;8666:5;-1:-1:-1;8723:2:1;8708:18;;8695:32;8736;8695;8736;:::i;:::-;8787:7;-1:-1:-1;8813:38:1;8846:3;8831:19;;8813:38;:::i;:::-;8803:48;;8870:38;8903:3;8892:9;8888:19;8870:38;:::i;:::-;8860:48;;8103:811;;;;;;;;:::o;8919:322::-;8988:6;9041:2;9029:9;9020:7;9016:23;9012:32;9009:52;;;9057:1;9054;9047:12;9009:52;9097:9;9084:23;-1:-1:-1;;;;;9122:6:1;9119:30;9116:50;;;9162:1;9159;9152:12;9116:50;9185;9227:7;9218:6;9207:9;9203:22;9185:50;:::i;9474:385::-;9560:6;9568;9576;9584;9637:3;9625:9;9616:7;9612:23;9608:33;9605:53;;;9654:1;9651;9644:12;9605:53;-1:-1:-1;;9677:23:1;;;9747:2;9732:18;;9719:32;;-1:-1:-1;9798:2:1;9783:18;;9770:32;;9849:2;9834:18;9821:32;;-1:-1:-1;9474:385:1;-1:-1:-1;9474:385:1:o;9864:339::-;9960:6;9968;10012:9;10003:7;9999:23;10042:3;10038:2;10034:12;10031:32;;;10059:1;10056;10049:12;10031:32;10082:23;;;-1:-1:-1;10139:3:1;-1:-1:-1;;10121:16:1;;10117:26;10114:46;;;10156:1;10153;10146:12;10114:46;;10194:2;10183:9;10179:18;10169:28;;9864:339;;;;;:::o;10208:1305::-;10355:6;10363;10371;10379;10387;10395;10403;10411;10464:3;10452:9;10443:7;10439:23;10435:33;10432:53;;;10481:1;10478;10471:12;10432:53;10521:9;10508:23;-1:-1:-1;;;;;10591:2:1;10583:6;10580:14;10577:34;;;10607:1;10604;10597:12;10577:34;10630:50;10672:7;10663:6;10652:9;10648:22;10630:50;:::i;:::-;10620:60;;10727:2;10716:9;10712:18;10699:32;10689:42;;10781:2;10770:9;10766:18;10753:32;10740:45;;10794:31;10819:5;10794:31;:::i;:::-;10844:5;;-1:-1:-1;10901:2:1;10886:18;;10873:32;;10914;10873;10914;:::i;:::-;10965:7;10955:17;;10991:38;11024:3;11013:9;11009:19;10991:38;:::i;:::-;10981:48;;11082:3;11071:9;11067:19;11054:33;11038:49;;11112:2;11102:8;11099:16;11096:36;;;11128:1;11125;11118:12;11096:36;11166:8;11155:9;11151:24;11141:34;;11213:7;11206:4;11202:2;11198:13;11194:27;11184:55;;11235:1;11232;11225:12;11184:55;11275:2;11262:16;11301:2;11293:6;11290:14;11287:34;;;11317:1;11314;11307:12;11287:34;11370:7;11365:2;11355:6;11352:1;11348:14;11344:2;11340:23;11336:32;11333:45;11330:65;;;11391:1;11388;11381:12;11330:65;11422:2;11418;11414:11;11404:21;;11444:6;11434:16;;;;;11469:38;11502:3;11491:9;11487:19;11469:38;:::i;:::-;11459:48;;10208:1305;;;;;;;;;;;:::o;11518:247::-;11577:6;11630:2;11618:9;11609:7;11605:23;11601:32;11598:52;;;11646:1;11643;11636:12;11598:52;11685:9;11672:23;11704:31;11729:5;11704:31;:::i;11952:383::-;12030:6;12038;12091:2;12079:9;12070:7;12066:23;12062:32;12059:52;;;12107:1;12104;12097:12;12059:52;12139:9;12133:16;12158:31;12183:5;12158:31;:::i;:::-;12258:2;12243:18;;12237:25;12208:5;;-1:-1:-1;12271:32:1;12237:25;12271:32;:::i;12649:277::-;12716:6;12769:2;12757:9;12748:7;12744:23;12740:32;12737:52;;;12785:1;12782;12775:12;12737:52;12817:9;12811:16;12870:5;12863:13;12856:21;12849:5;12846:32;12836:60;;12892:1;12889;12882:12;12931:336;13133:2;13115:21;;;13172:2;13152:18;;;13145:30;-1:-1:-1;;;13206:2:1;13191:18;;13184:42;13258:2;13243:18;;12931:336::o;13272:251::-;13342:6;13395:2;13383:9;13374:7;13370:23;13366:32;13363:52;;;13411:1;13408;13401:12;13363:52;13443:9;13437:16;13462:31;13487:5;13462:31;:::i;13528:249::-;13597:6;13650:2;13638:9;13629:7;13625:23;13621:32;13618:52;;;13666:1;13663;13656:12;13618:52;13698:9;13692:16;13717:30;13741:5;13717:30;:::i;13782:423::-;13824:3;13862:5;13856:12;13889:6;13884:3;13877:19;13914:1;13924:162;13938:6;13935:1;13932:13;13924:162;;;14000:4;14056:13;;;14052:22;;14046:29;14028:11;;;14024:20;;14017:59;13953:12;13924:162;;;13928:3;14131:1;14124:4;14115:6;14110:3;14106:16;14102:27;14095:38;14194:4;14187:2;14183:7;14178:2;14170:6;14166:15;14162:29;14157:3;14153:39;14149:50;14142:57;;;13782:423;;;;:::o;14210:782::-;14530:6;14519:9;14512:25;14573:3;14568:2;14557:9;14553:18;14546:31;14493:4;14594:46;14635:3;14624:9;14620:19;14612:6;14594:46;:::i;:::-;-1:-1:-1;;;;;14714:15:1;;;14709:2;14694:18;;14687:43;14766:15;;;;14761:2;14746:18;;14739:43;-1:-1:-1;;;;;14856:15:1;;;14850:3;14835:19;;14828:44;14921:10;14909:23;;;;14667:3;14888:19;;14881:52;14970:15;;;14964:3;14949:19;;;14942:44;14586:54;14210:782;-1:-1:-1;;;14210:782:1:o;15276:652::-;15337:5;15390:3;15383:4;15375:6;15371:17;15367:27;15357:55;;15408:1;15405;15398:12;15357:55;15441:2;15435:9;15483:3;15475:6;15471:16;15553:6;15541:10;15538:22;-1:-1:-1;;;;;15505:10:1;15502:34;15499:62;15496:88;;;15564:18;;:::i;:::-;15600:2;15593:22;15635:6;15676:3;15664:16;;15692:15;;;15689:35;;;15720:1;15717;15710:12;15689:35;15744:6;15759:139;15775:6;15770:3;15767:15;15759:139;;;15843:10;;15831:23;;15883:4;15874:14;;;;15792;15759:139;;;-1:-1:-1;15916:6:1;;15276:652;-1:-1:-1;;;;;15276:652:1:o;15933:830::-;16029:6;16082:3;16070:9;16061:7;16057:23;16053:33;16050:53;;;16099:1;16096;16089:12;16050:53;16132:2;16126:9;16174:4;16166:6;16162:17;16245:6;16233:10;16230:22;-1:-1:-1;;;;;16197:10:1;16194:34;16191:62;16188:88;;;16256:18;;:::i;:::-;16292:2;16285:22;16331:16;;16316:32;;16381:64;16437:7;16432:2;16417:18;;16381:64;:::i;:::-;16376:2;16368:6;16364:15;16357:89;16479:66;16537:7;16530:4;16519:9;16515:20;16479:66;:::i;:::-;16474:2;16462:15;;16455:91;16602:3;16587:19;;16581:26;16574:4;16562:17;;16555:53;16664:3;16649:19;;16643:26;16636:4;16624:17;;16617:53;16726:3;16711:19;;;16705:26;16698:4;16686:17;;16679:53;-1:-1:-1;16466:6:1;15933:830;-1:-1:-1;15933:830:1:o;16768:184::-;16838:6;16891:2;16879:9;16870:7;16866:23;16862:32;16859:52;;;16907:1;16904;16897:12;16859:52;-1:-1:-1;16930:16:1;;16768:184;-1:-1:-1;16768:184:1:o;16957:127::-;17018:10;17013:3;17009:20;17006:1;16999:31;17049:4;17046:1;17039:15;17073:4;17070:1;17063:15;17089:128;17156:9;;;17177:11;;;17174:37;;;17191:18;;:::i;17222:168::-;17295:9;;;17326;;17343:15;;;17337:22;;17323:37;17313:71;;17364:18;;:::i;17739:337::-;17941:2;17923:21;;;17980:2;17960:18;;;17953:30;-1:-1:-1;;;18014:2:1;17999:18;;17992:43;18067:2;18052:18;;17739:337::o;18081:249::-;18152:10;18194;;;18206;;;18190:27;18237:20;;;;18152:10;18276:24;;;18266:58;;18304:18;;:::i;:::-;18266:58;;18081:249;;;;:::o;18335:180::-;-1:-1:-1;;;;;18440:10:1;;;18452;;;18436:27;;18475:11;;;18472:37;;;18489:18;;:::i;:::-;18472:37;18335:180;;;;:::o;18865:385::-;19068:6;19057:9;19050:25;19111:2;19106;19095:9;19091:18;19084:30;19031:4;19131:45;19172:2;19161:9;19157:18;19149:6;19131:45;:::i;:::-;19123:53;;-1:-1:-1;;;;;19216:6:1;19212:31;19207:2;19196:9;19192:18;19185:59;18865:385;;;;;;:::o;19255:548::-;19514:3;19503:9;19496:22;19477:4;19535:46;19576:3;19565:9;19561:19;19553:6;19535:46;:::i;:::-;19612:2;19597:18;;19590:34;;;;-1:-1:-1;;;;;;19660:32:1;;;;19655:2;19640:18;;19633:60;19741:10;19729:23;;;;19724:2;19709:18;;19702:51;19784:3;19769:19;;;19762:35;19527:54;19255:548;-1:-1:-1;19255:548:1:o;19808:135::-;19847:3;19868:17;;;19865:43;;19888:18;;:::i;:::-;-1:-1:-1;19935:1:1;19924:13;;19808:135::o;19948:127::-;20009:10;20004:3;20000:20;19997:1;19990:31;20040:4;20037:1;20030:15;20064:4;20061:1;20054:15;20080:125;20145:9;;;20166:10;;;20163:36;;;20179:18;;:::i;20210:335::-;20412:2;20394:21;;;20451:2;20431:18;;;20424:30;-1:-1:-1;;;20485:2:1;20470:18;;20463:41;20536:2;20521:18;;20210:335::o;22818:420::-;23073:25;;;-1:-1:-1;;;;;23134:32:1;;23129:2;23114:18;;23107:60;23060:3;23045:19;;23176:56;23228:2;23213:18;;23205:6;23176:56;:::i;23243:217::-;23283:1;23309;23299:132;;23353:10;23348:3;23344:20;23341:1;23334:31;23388:4;23385:1;23378:15;23416:4;23413:1;23406:15;23299:132;-1:-1:-1;23445:9:1;;23243:217::o;26988:151::-;27078:4;27071:12;;;27057;;;27053:31;;27096:14;;27093:40;;;27113:18;;:::i

Swarm Source

ipfs://a037b31ec1e705082799c5c6fd1e2cbeede0b4078a202915acb97fbfda673721

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.