Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x9acbab7d7c5a65c151738a1153777a55d3a295b015b40fa765cb59827e81310a | 0x60806040 | 11370521 | 692 days 6 hrs ago | 0xb013abd83f0bd173e9f14ce7d6e420ad711483b4 | IN | Create: AdvancedQuesting | 0 ETH | 0.03582571448 ETH |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
AdvancedQuesting
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @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 IERC1155Upgradeable is IERC165Upgradeable { /** * @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 be 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.0; import "./ERC1155ReceiverUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. * * @dev _Available since v3.1._ */ contract ERC1155HolderUpgradeable is Initializable, ERC1155ReceiverUpgradeable { function __ERC1155Holder_init() internal onlyInitializing { } function __ERC1155Holder_init_unchained() internal onlyInitializing { } function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) pragma solidity ^0.8.0; import "../IERC1155ReceiverUpgradeable.sol"; import "../../../utils/introspection/ERC165Upgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable { function __ERC1155Receiver_init() internal onlyInitializing { } function __ERC1155Receiver_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @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`, 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 be 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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; import "../IERC721ReceiverUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable { function __ERC721Holder_init() internal onlyInitializing { } function __ERC721Holder_init_unchained() internal onlyInitializing { } /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // 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 IERC165Upgradeable { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./AdvancedQuestingSettings.sol"; contract AdvancedQuesting is Initializable, AdvancedQuestingSettings { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; function initialize() external initializer { AdvancedQuestingSettings.__AdvancedQuestingSettings_init(); } function startAdvancedQuesting(StartQuestParams[] calldata _params) external whenNotPaused contractsAreSet onlyEOA { require(_params.length > 0, "No start quest params given"); for(uint256 i = 0; i < _params.length; i++) { _startAdvancedQuesting(_params[i]); } } function _startAdvancedQuesting(StartQuestParams calldata _startQuestParams) private { uint256 _legionId = _startQuestParams.legionId; require(!isLegionQuesting(_legionId), "Legion is already questing"); require(isValidZone(_startQuestParams.zoneName), "Invalid zone"); uint256 _numberOfParts = numberOfPartsInZone(_startQuestParams.zoneName); require(_startQuestParams.advanceToPart > 0 && _startQuestParams.advanceToPart <= _numberOfParts, "Invalid advance to part"); LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_legionId); require(_legionMetadata.legionGeneration != LegionGeneration.RECRUIT, "Recruit cannot advanced quest"); bool _willPlayTreasureTriad = false; // Need to check that they have the correct level to advance through the given parts of the quest. for(uint256 i = 0; i < _startQuestParams.advanceToPart; i++) { uint8 _levelRequirement = zoneNameToInfo[_startQuestParams.zoneName].parts[i].questingLevelRequirement; require(_legionMetadata.questLevel >= _levelRequirement, "Legion not high enough questing level"); bool _treasureTriadOnThisPart = zoneNameToInfo[_startQuestParams.zoneName].parts[i].playTreasureTriad; _willPlayTreasureTriad = _willPlayTreasureTriad || _treasureTriadOnThisPart; // Also, if a part has a treasure triad game and it is not the last part, they cannot auto advance past it. if(i < _startQuestParams.advanceToPart - 1 && _treasureTriadOnThisPart) { revert("Cannot advanced past a part that requires treasure triad"); } } require(_startQuestParams.treasureIds.length == _startQuestParams.treasureAmounts.length, "Bad treasure lengths"); require(!_willPlayTreasureTriad || _startQuestParams.treasureIds.length > 0, "Need treasure to play treasure triad"); uint256 _totalTreasureAmounts = 0; uint8 _maxConstellationRank = _maxConstellationRankForLegionAndZone(_startQuestParams.zoneName, _legionMetadata); for(uint256 i = 0; i < _startQuestParams.treasureIds.length; i++) { require(_startQuestParams.treasureIds[i] > 0 && _startQuestParams.treasureAmounts[i] > 0, "Bad treasure id or amount"); _totalTreasureAmounts += _startQuestParams.treasureAmounts[i]; require(_totalTreasureAmounts <= _maxConstellationRank, "Too many treasures for constellation rank"); } uint256 _requestId = randomizer.requestRandomNumber(); legionIdToLegionQuestingInfo[_legionId].startTime = block.timestamp; legionIdToLegionQuestingInfo[_legionId].requestId = _requestId; legionIdToLegionQuestingInfo[_legionId].zoneName = _startQuestParams.zoneName; legionIdToLegionQuestingInfo[_legionId].owner = msg.sender; legionIdToLegionQuestingInfo[_legionId].advanceToPart = _startQuestParams.advanceToPart; legionIdToLegionQuestingInfo[_legionId].currentPart = 0; delete legionIdToLegionQuestingInfo[_legionId].triadOutcome; for(uint256 i = 0; i < _startQuestParams.treasureIds.length; i++) { uint256 _treasureId = _startQuestParams.treasureIds[i]; require(!legionIdToLegionQuestingInfo[_legionId].treasureIds.contains(_treasureId), "Duplicate treasure id in array"); legionIdToLegionQuestingInfo[_legionId].treasureIds.add(_treasureId); legionIdToLegionQuestingInfo[_legionId].treasureIdToAmount[_treasureId] = _startQuestParams.treasureAmounts[i]; } // Transfer legion and treasure to this contract. legion.adminSafeTransferFrom(msg.sender, address(this), _legionId); if(_startQuestParams.treasureIds.length > 0) { treasure.safeBatchTransferFrom( msg.sender, address(this), _startQuestParams.treasureIds, _startQuestParams.treasureAmounts, ""); } emit AdvancedQuestStarted( msg.sender, _requestId, _startQuestParams); } function continueAdvancedQuesting(uint256[] calldata _legionIds) external whenNotPaused contractsAreSet onlyEOA nonZeroLength(_legionIds) { for(uint256 i = 0; i < _legionIds.length; i++) { _continueAdvancedQuesting(_legionIds[i]); } } function _continueAdvancedQuesting(uint256 _legionId) private { LegionQuestingInfo storage _legionQuestingInfo = legionIdToLegionQuestingInfo[_legionId]; LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_legionId); ZoneInfo storage _zoneInfo = zoneNameToInfo[_legionQuestingInfo.zoneName]; require(_legionQuestingInfo.owner == msg.sender, "Legion is not yours"); uint256 _randomNumber = randomizer.revealRandomNumber(legionIdToLegionQuestingInfo[_legionId].requestId); _ensureDoneWithCurrentPart(_legionId, _legionQuestingInfo, _legionMetadata, _zoneInfo, _randomNumber, true); // Ensure we are not continuing too far. require(_legionQuestingInfo.advanceToPart + 1 <= _zoneInfo.parts.length, "Already at last part"); // Check if player can even advance to part. // Using advancedToPart as index because it is the index of the next part. require(_legionMetadata.questLevel >= _zoneInfo.parts[_legionQuestingInfo.advanceToPart].questingLevelRequirement, "Legion not high enough questing level"); // If the next part has a triad requirement, must have treasure staked still. require(!_zoneInfo.parts[_legionQuestingInfo.advanceToPart].playTreasureTriad || _legionQuestingInfo.treasureIds.length() > 0, "No treasure staked for legion"); // Need new number for stasis role + potentially treasure triad. uint256 _requestId = randomizer.requestRandomNumber(); _legionQuestingInfo.startTime = block.timestamp; _legionQuestingInfo.currentPart = _legionQuestingInfo.advanceToPart; _legionQuestingInfo.advanceToPart++; delete _legionQuestingInfo.triadOutcome; _legionQuestingInfo.requestId = _requestId; emit AdvancedQuestContinued(msg.sender, _legionId, _requestId, _legionQuestingInfo.advanceToPart); } // Ends questing at the current part. Must have played triad if triad is required on current part. function endQuesting( uint256[] calldata _legionIds) external whenNotPaused contractsAreSet onlyEOA nonZeroLength(_legionIds) { for(uint256 i = 0; i < _legionIds.length; i++) { _endQuesting(_legionIds[i]); } } function _endQuesting(uint256 _legionId) private { LegionQuestingInfo storage _legionQuestingInfo = legionIdToLegionQuestingInfo[_legionId]; LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_legionId); ZoneInfo storage _zoneInfo = zoneNameToInfo[_legionQuestingInfo.zoneName]; require(_legionQuestingInfo.owner == msg.sender, "Legion is not yours"); uint256 _randomNumber = randomizer.revealRandomNumber(legionIdToLegionQuestingInfo[_legionId].requestId); _ensureDoneWithCurrentPart(_legionId, _legionQuestingInfo, _legionMetadata, _zoneInfo, _randomNumber, true); _endQuestingPostValidation(_legionId, _legionQuestingInfo, _legionMetadata, _zoneInfo, _randomNumber); } function _endQuestingPostValidation( uint256 _legionId, LegionQuestingInfo storage _legionQuestingInfo, LegionMetadata memory _legionMetadata, ZoneInfo storage _zoneInfo, uint256 _randomNumber) private { questing.processQPGainAndLevelUp(_legionId, _legionMetadata.questLevel); AdvancedQuestReward[] memory _earnedRewards = _distributeRewards(_legionQuestingInfo, _legionMetadata, _zoneInfo, _randomNumber); // Only need to delete the start time to save on gas. Acts as a flag if the legion is questing. // When startQuesting is called all LegionQuestingInfo fields will be overridden. delete _legionQuestingInfo.startTime; // Send back legion and treasure legion.adminSafeTransferFrom(address(this), msg.sender, _legionId); uint256[] memory _treasureIds = _legionQuestingInfo.treasureIds.values(); uint256[] memory _treasureAmounts = new uint256[](_treasureIds.length); for(uint256 i = 0; i < _treasureIds.length; i++) { _legionQuestingInfo.treasureIds.remove(_treasureIds[i]); _treasureAmounts[i] = _legionQuestingInfo.treasureIdToAmount[_treasureIds[i]]; } if(_treasureIds.length > 0) { treasure.safeBatchTransferFrom( address(this), msg.sender, _treasureIds, _treasureAmounts, ""); } emit AdvancedQuestEnded(msg.sender, _legionId, _earnedRewards); } function _distributeRewards( LegionQuestingInfo storage _legionQuestingInfo, LegionMetadata memory _legionMetadata, ZoneInfo storage _zoneInfo, uint256 _randomNumber) private returns(AdvancedQuestReward[] memory) { // Gain Rewards! ZonePart storage _endingPart = _zoneInfo.parts[_legionQuestingInfo.advanceToPart - 1]; // The returned random number was used for stasis calculations. Scramble the number with a constant. _randomNumber = uint256(keccak256(abi.encode(_randomNumber, 17647295972771752179227871979083739911846583376458796885201641052640283607576))); uint256 _legionGeneration = uint256(_legionMetadata.legionGeneration); uint256 _legionRarity = uint256(_legionMetadata.legionRarity); AdvancedQuestReward[] memory _earnedRewards = new AdvancedQuestReward[](_endingPart.rewards.length); for(uint256 i = 0; i < _endingPart.rewards.length; i++) { ZoneReward storage _reward = _endingPart.rewards[i]; uint256 _odds = _reward.baseRateRewardOdds + _reward.generationToRarityToBoost[_legionGeneration][_legionRarity] + (_reward.boostPerFlippedCard * _legionQuestingInfo.triadOutcome.cardsFlipped); bool _hitReward; if(_odds >= 255) { _hitReward = true; } else if(_odds > 0) { if(_randomNumber % 256 < _odds) { _hitReward = true; } _randomNumber >>= 8; } if(_hitReward) { ZoneRewardOption storage _zoneRewardOption = _pickRewardFromOptions(_randomNumber, _reward); if(_zoneRewardOption.consumableId > 0 && _zoneRewardOption.consumableAmount > 0) { _earnedRewards[i].consumableId = _zoneRewardOption.consumableId; _earnedRewards[i].consumableAmount = _zoneRewardOption.consumableAmount; consumable.mint( msg.sender, _zoneRewardOption.consumableId, _zoneRewardOption.consumableAmount); } if(_zoneRewardOption.treasureFragmentId > 0) { _earnedRewards[i].treasureFragmentId = _zoneRewardOption.treasureFragmentId; treasureFragment.mint( msg.sender, _zoneRewardOption.treasureFragmentId, 1); } if(_zoneRewardOption.treasureTier > 0) { uint256 _treasureId = treasureMetadataStore.getRandomTreasureForTierAndCategory( _zoneRewardOption.treasureTier, _zoneRewardOption.treasureCategory, _randomNumber); _earnedRewards[i].treasureId = _treasureId; treasure.mint( msg.sender, _treasureId, 1); } _randomNumber >>= 8; } } return _earnedRewards; } function _pickRewardFromOptions( uint256 _randomNumber, ZoneReward storage _zoneReward) private view returns(ZoneRewardOption storage) { // Gas optimization. Only run random calculations for rewards with more than 1 option. if(_zoneReward.rewardOptions.length == 1) { return _zoneReward.rewardOptions[0]; } uint256 _result = _randomNumber % 256; uint256 _topRange = 0; _randomNumber >>= 8; for(uint256 j = 0; j < _zoneReward.rewardOptions.length; j++) { ZoneRewardOption storage _zoneRewardOption = _zoneReward.rewardOptions[j]; _topRange += _zoneRewardOption.rewardOdds; if(_result < _topRange) { // Got this reward! return _zoneRewardOption; } } revert("Bad odds for zone reward"); } function playTreasureTriad( uint256[] calldata _legionIds, UserMove[][] calldata _playerMoves, bool[] calldata _endQuestingAfterPlayingIfPossible) external whenNotPaused contractsAreSet onlyEOA nonZeroLength(_legionIds) { require(_legionIds.length == _playerMoves.length && _legionIds.length == _endQuestingAfterPlayingIfPossible.length, "Bad array lengths for play"); for(uint256 i = 0; i < _legionIds.length; i++) { _playTreasureTriad(_legionIds[i], _playerMoves[i], _endQuestingAfterPlayingIfPossible[i]); } } function _playTreasureTriad(uint256 _legionId, UserMove[] calldata _playerMoves, bool _endQuestingIfPossible) private { LegionQuestingInfo storage _legionQuestingInfo = legionIdToLegionQuestingInfo[_legionId]; LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_legionId); ZoneInfo storage _zoneInfo = zoneNameToInfo[_legionQuestingInfo.zoneName]; require(_legionQuestingInfo.owner == msg.sender, "Legion is not yours"); uint256 _randomNumber = randomizer.revealRandomNumber(legionIdToLegionQuestingInfo[_legionId].requestId); // Don't check for triad as they will be playing it right now. _ensureDoneWithCurrentPart(_legionId, _legionQuestingInfo, _legionMetadata, _zoneInfo, _randomNumber, false); _validatePlayerHasTreasuresForMoves(_playerMoves, _legionQuestingInfo); GameOutcome memory _outcome = treasureTriad.generateBoardAndPlayGame( _randomNumber, _legionMetadata.legionClass, _playerMoves); // Timestamp used to verify they have played and to calculate the length of stasis post game. _legionQuestingInfo.triadOutcome.timeTriadWasPlayed = block.timestamp; _legionQuestingInfo.triadOutcome.corruptedCellsRemainingForCurrentPart = _outcome.numberOfCorruptedCardsLeft; _legionQuestingInfo.triadOutcome.cardsFlipped = _outcome.numberOfFlippedCards; emit TreasureTriadPlayed(msg.sender, _legionId, _outcome.playerWon, _outcome.numberOfFlippedCards, _outcome.numberOfCorruptedCardsLeft); // If there are any corrupted cards left, they will be stuck in stasis and cannot end now. if(_endQuestingIfPossible && _outcome.numberOfCorruptedCardsLeft == 0) { _endQuestingPostValidation(_legionId, _legionQuestingInfo, _legionMetadata, _zoneInfo, _randomNumber); } } function _validatePlayerHasTreasuresForMoves(UserMove[] calldata _playerMoves, LegionQuestingInfo storage _legionQuestingInfo) private view { // Before sending to the treasure triad contract, ensure they have staked the treasures and can play them. // The treasure triad contract will handle the game logic, and validating that the player moves are valid. require(_playerMoves.length > 0 && _playerMoves.length < 4, "Bad number of treasure triad moves"); // Worst case, they have 3 different treasures. Treasure[] memory _treasures = new Treasure[](_playerMoves.length); uint256 _treasureIndex = 0; for(uint256 i = 0; i < _playerMoves.length; i++) { uint256 _treasureIdForMove = _playerMoves[i].treasureId; require(_legionQuestingInfo.treasureIds.contains(_treasureIdForMove), "Cannot play treasure that was not staked"); bool _foundLocalTreasure = false; for(uint256 k = 0; k < _treasures.length; k++) { if(_treasures[k].id == _treasureIdForMove) { _foundLocalTreasure = true; if(_treasures[k].amount == 0) { revert("Used more treasure than what was staked"); } else { _treasures[k].amount--; } break; } } if(!_foundLocalTreasure) { _treasures[_treasureIndex] = Treasure(_treasureIdForMove, _legionQuestingInfo.treasureIdToAmount[_treasureIdForMove] - 1); _treasureIndex++; } } } // Ensures the legion is done with the current part they are on. // This includes checking the end time and making sure they played treasure triad. function _ensureDoneWithCurrentPart( uint256 _legionId, LegionQuestingInfo storage _legionQuestingInfo, LegionMetadata memory _legionMetadata, ZoneInfo storage _zoneInfo, uint256 _randomNumber, bool _checkPlayedTriad) private view { uint8 _maxConstellationRank = _maxConstellationRankForLegionAndZone( _legionQuestingInfo.zoneName, _legionMetadata); // Handles checking if the legion is questing or not. Will revert if not. // Handles checking if stasis random is ready. Will revert if not. (uint256 _endTime,) = _endTimeForLegion(_legionId, _legionMetadata, _maxConstellationRank, _randomNumber); require(block.timestamp >= _endTime, "Legion has not finished this part of the zone yet"); // Triad played check. Only need to check the last part as _startAdvancedQuesting would have reverted // if they tried to skip past a triad played check. if(_checkPlayedTriad && _zoneInfo.parts[_legionQuestingInfo.advanceToPart - 1].playTreasureTriad && _legionQuestingInfo.triadOutcome.timeTriadWasPlayed == 0) { revert("Has not played treasure triad for current part"); } } function isLegionQuesting(uint256 _legionId) public view returns(bool) { return legionIdToLegionQuestingInfo[_legionId].startTime > 0; } function numberOfPartsInZone(string calldata _zoneName) public view returns(uint256) { return zoneNameToInfo[_zoneName].parts.length; } // Returns the end time for the legion and the number of stasis hit in all the parts of the zone. // If the legion is waiting through stasis caused by corrupt cards in treasure triad, the second number will be the number of cards remaining. function endTimeForLegion(uint256 _legionId) external view returns(uint256, uint8) { LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_legionId); uint8 _maxConstellationRank = _maxConstellationRankForLegionAndZone( legionIdToLegionQuestingInfo[_legionId].zoneName, _legionMetadata); uint256 _randomNumber = randomizer.revealRandomNumber(legionIdToLegionQuestingInfo[_legionId].requestId); return _endTimeForLegion(_legionId, _legionMetadata, _maxConstellationRank, _randomNumber); } function _endTimeForLegion( uint256 _legionId, LegionMetadata memory _legionMetadata, uint8 _maxConstellationRank, uint256 _randomNumber) private view returns(uint256, uint8) { require(isLegionQuesting(_legionId), "Legion is not questing"); LegionQuestingInfo storage _legionQuestingInfo = legionIdToLegionQuestingInfo[_legionId]; ZoneInfo storage _zoneInfo = zoneNameToInfo[_legionQuestingInfo.zoneName]; uint256 _triadPlayTime = _legionQuestingInfo.triadOutcome.timeTriadWasPlayed; uint256 _corruptCellsRemaining = _legionQuestingInfo.triadOutcome.corruptedCellsRemainingForCurrentPart; // If this part requires treasure triad, and the user has already played it for this part, // AND the use had a corrupted card... the end time will be based on that stasis. if(_zoneInfo.parts[_legionQuestingInfo.advanceToPart - 1].playTreasureTriad && _triadPlayTime > 0 && _corruptCellsRemaining > 0) { return (_triadPlayTime + (_corruptCellsRemaining * stasisLengthForCorruptedCard), uint8(_corruptCellsRemaining)); } uint256 _totalLength = 0; uint8 _baseRateReduction = maxConstellationRankToReductionInStasis[_maxConstellationRank]; uint8 _stasisHitCount = 0; // For example, assume currentPart is 0 and they are advancing to part 1. // We will go through this for loop once. The first time, i = 0, which is also // the index of the parts array in the ZoneInfo object. for(uint256 i = _legionQuestingInfo.currentPart; i < _legionQuestingInfo.advanceToPart; i++) { _totalLength += _zoneInfo.parts[i].zonePartLength; if(generationToCanHaveStasis[_legionMetadata.legionGeneration]) { uint8 _baseRate = _zoneInfo.parts[i].stasisBaseRate; // If not greater than, no chance of stasis! if(_baseRate > _baseRateReduction) { if(_randomNumber % 256 < _baseRate - _baseRateReduction) { _stasisHitCount++; _totalLength += _zoneInfo.parts[i].stasisLength; } _randomNumber >>= 8; } } } return (legionIdToLegionQuestingInfo[_legionId].startTime + _totalLength, _stasisHitCount); } function currentPartForLegion(uint256 _legionId) external view returns(uint8) { return legionIdToLegionQuestingInfo[_legionId].currentPart; } function advanceToPartForLegion(uint256 _legionId) external view returns(uint8) { return legionIdToLegionQuestingInfo[_legionId].advanceToPart; } function _maxConstellationRankForLegionAndZone( string memory _zoneName, LegionMetadata memory _legionMetadata) private view returns(uint8) { uint8 _rankConstellation1 = _legionMetadata.constellationRanks[uint256(zoneNameToInfo[_zoneName].constellation1)]; uint8 _rankConstellation2 = _legionMetadata.constellationRanks[uint256(zoneNameToInfo[_zoneName].constellation2)]; if(_rankConstellation1 > _rankConstellation2) { return _rankConstellation1; } else { return _rankConstellation2; } } } struct Treasure { uint256 id; uint256 amount; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./AdvancedQuestingState.sol"; abstract contract AdvancedQuestingContracts is Initializable, AdvancedQuestingState { function __AdvancedQuestingContracts_init() internal initializer { AdvancedQuestingState.__AdvancedQuestingState_init(); } function setContracts( address _randomizerAddress, address _questingAddress, address _legionAddress, address _legionMetadataStoreAddress, address _treasureAddress, address _consumableAddress, address _treasureMetadataStoreAddress, address _treasureTriadAddress, address _treasureFragmentAddress) external onlyAdminOrOwner { randomizer = IRandomizer(_randomizerAddress); questing = IQuesting(_questingAddress); legion = ILegion(_legionAddress); legionMetadataStore = ILegionMetadataStore(_legionMetadataStoreAddress); treasure = ITreasure(_treasureAddress); consumable = IConsumable(_consumableAddress); treasureMetadataStore = ITreasureMetadataStore(_treasureMetadataStoreAddress); treasureTriad = ITreasureTriad(_treasureTriadAddress); treasureFragment = ITreasureFragment(_treasureFragmentAddress); } modifier contractsAreSet() { require(areContractsSet(), "Contracts aren't set"); _; } function areContractsSet() public view returns(bool) { return address(randomizer) != address(0) && address(questing) != address(0) && address(legion) != address(0) && address(legionMetadataStore) != address(0) && address(treasure) != address(0) && address(consumable) != address(0) && address(treasureMetadataStore) != address(0) && address(treasureTriad) != address(0) && address(treasureFragment) != address(0); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./AdvancedQuestingContracts.sol"; abstract contract AdvancedQuestingSettings is Initializable, AdvancedQuestingContracts { function __AdvancedQuestingSettings_init() internal initializer { AdvancedQuestingContracts.__AdvancedQuestingContracts_init(); } function addZone(string calldata _zoneName, ZoneInfo calldata _zone) external onlyAdminOrOwner { require(!compareStrings(_zoneName, ""), "Zone name cannot be blank"); require(!isValidZone(_zoneName), "Zone already exists"); require(_zone.zoneStartTime > 0, "Zone must have a start time"); zoneNameToInfo[_zoneName] = _zone; } function updatePartLengthsForZone( string calldata _zoneName, uint256[] calldata _partLengths, uint256[] calldata _stasisLengths) external onlyAdminOrOwner { require(isValidZone(_zoneName), "Zone is invalid"); ZoneInfo storage _zoneInfo = zoneNameToInfo[_zoneName]; require(_partLengths.length == _zoneInfo.parts.length && _partLengths.length == _stasisLengths.length, "Bad array lengths"); for(uint256 i = 0; i < _partLengths.length; i++) { _zoneInfo.parts[i].zonePartLength = _partLengths[i]; _zoneInfo.parts[i].stasisLength = _stasisLengths[i]; } } function setStasisLengthForCorruptedCard(uint256 _stasisLengthForCorruptedCard) external onlyAdminOrOwner { stasisLengthForCorruptedCard = _stasisLengthForCorruptedCard; } function isValidZone(string calldata _zoneName) public view returns(bool) { return zoneNameToInfo[_zoneName].zoneStartTime > 0; } function lengthForPartOfZone(string calldata _zoneName, uint8 _partIndex) public view returns(uint256) { return zoneNameToInfo[_zoneName].parts[_partIndex].zonePartLength; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol"; import "../../shared/randomizer/IRandomizer.sol"; import "./IAdvancedQuesting.sol"; import "../../shared/AdminableUpgradeable.sol"; import "../questing/IQuesting.sol"; import "../legion/ILegion.sol"; import "../legionmetadatastore/ILegionMetadataStore.sol"; import "../external/ITreasure.sol"; import "../consumable/IConsumable.sol"; import "../treasuremetadatastore/ITreasureMetadataStore.sol"; import "../treasuretriad/ITreasureTriad.sol"; import "../treasurefragment/ITreasureFragment.sol"; abstract contract AdvancedQuestingState is Initializable, IAdvancedQuesting, AdminableUpgradeable, ERC721HolderUpgradeable, ERC1155HolderUpgradeable { event AdvancedQuestStarted(address _owner, uint256 _requestId, StartQuestParams _startQuestParams); event AdvancedQuestContinued(address _owner, uint256 _legionId, uint256 _requestId, uint8 _toPart); event TreasureTriadPlayed(address _owner, uint256 _legionId, bool _playerWon, uint8 _numberOfCardsFlipped, uint8 _numberOfCorruptedCardsRemaining); event AdvancedQuestEnded(address _owner, uint256 _legionId, AdvancedQuestReward[] _rewards); // Used for event. Free to change struct AdvancedQuestReward { uint256 consumableId; uint256 consumableAmount; uint256 treasureFragmentId; // Assumed to be 1. uint256 treasureId; // Assumed to be 1. } IRandomizer public randomizer; IQuesting public questing; ILegion public legion; ILegionMetadataStore public legionMetadataStore; ITreasure public treasure; IConsumable public consumable; ITreasureMetadataStore public treasureMetadataStore; ITreasureTriad public treasureTriad; ITreasureFragment public treasureFragment; // The length of stasis per corrupted card. uint256 public stasisLengthForCorruptedCard; // The name of the zone to all of mapping(string => ZoneInfo) public zoneNameToInfo; // For a given generation, returns if they can experience stasis. mapping(LegionGeneration => bool) generationToCanHaveStasis; // The highest constellation rank for the given zone to how much the chance of stasis is reduced. // The value that is stored is out of 256, as is the probability calculation. mapping(uint8 => uint8) maxConstellationRankToReductionInStasis; mapping(uint256 => LegionQuestingInfo) internal legionIdToLegionQuestingInfo; function __AdvancedQuestingState_init() internal initializer { AdminableUpgradeable.__Adminable_init(); ERC721HolderUpgradeable.__ERC721Holder_init(); ERC1155HolderUpgradeable.__ERC1155Holder_init(); stasisLengthForCorruptedCard = 1 days; generationToCanHaveStasis[LegionGeneration.GENESIS] = false; generationToCanHaveStasis[LegionGeneration.AUXILIARY] = true; maxConstellationRankToReductionInStasis[1] = 10; maxConstellationRankToReductionInStasis[2] = 15; maxConstellationRankToReductionInStasis[3] = 20; maxConstellationRankToReductionInStasis[4] = 23; maxConstellationRankToReductionInStasis[5] = 38; maxConstellationRankToReductionInStasis[6] = 51; maxConstellationRankToReductionInStasis[7] = 64; } } struct LegionQuestingInfo { // Will be 0 if not on a quest. // The time that the legion started the CURRENT part. uint256 startTime; // The current random request for the legion. // There may be multiple requests through the zone parts depending // on if they auto-advanced or not. uint256 requestId; // The outcome of treasure triad for the part the user ends on (advanceToPart). LegionTriadOutcome triadOutcome; // The ids of the treasure that was staked along with this legion. // May be empty. If empty, user cannot play treasure triad. EnumerableSetUpgradeable.UintSet treasureIds; mapping(uint256 => uint256) treasureIdToAmount; // The zone they are currently at. string zoneName; // The owner of this questing. This value only should be trusted if startTime > 0 and the legion is staked here. address owner; // Indicates how far the legion wants to go automatically. uint8 advanceToPart; // Which part the legion is currently at. May be 0 if they have not made it to part 1. uint8 currentPart; } struct LegionTriadOutcome { // If 0, triad has not been played for current part. uint256 timeTriadWasPlayed; // Indicates the number of corrupted cards that were left for the current part the legion is on. uint8 corruptedCellsRemainingForCurrentPart; // Number of cards flipped uint8 cardsFlipped; } struct ZoneInfo { // The time this zone becomes active. If 0, zone does not exist. uint256 zoneStartTime; TreasureCategory categoryBoost1; TreasureCategory categoryBoost2; // The constellations that are considered for this zone. Constellation constellation1; Constellation constellation2; ZonePart[] parts; } struct ZonePart { // The length of time this zone takes to complete. uint256 zonePartLength; // The length of time added to the journey if the legion gets stasis. uint256 stasisLength; // The base rate of statis for the part of the zone. Out of 256. uint8 stasisBaseRate; // The quest level minimum required to proceed to this part of the zone. uint8 questingLevelRequirement; // DEPRECATED uint8 questingXpGained; // Indicates if the user needs to play treasure triad to complete this part of the journey. bool playTreasureTriad; // The different rewards given if the user ends their adventure on this part of the zone. ZoneReward[] rewards; } struct ZoneReward { // Out of 256 (255 max). How likely this reward group will be given to the user. uint8 baseRateRewardOdds; // Certain generations/rarities get a rate boost. // For example, only genesis legions are able to get full treasures from the zone. // And each rarity of legions (genesis and auxiliary) have a better chance for treasure pieces. uint8[][] generationToRarityToBoost; // Applies only when this zone part requires the user to play treasure triad. // This is the boost this reward gains per card that was flipped by the user. uint8 boostPerFlippedCard; // The different options for this reward. ZoneRewardOption[] rewardOptions; } struct ZoneRewardOption { // The consumable id associated with this reward option. // May be 0. uint256 consumableId; // The amount of the consumable given. uint256 consumableAmount; // ID associated to this treasure fragment. May be 0. uint256 treasureFragmentId; // The treasure tier if this option is to receive a full treasure. // May be 0 indicating no treasures uint8 treasureTier; // The category of treasure that will be minted for the given tier. TreasureCategory treasureCategory; // The odds out of 256 that this reward is picked from the options uint8 rewardOdds; } struct StartQuestParams { uint256 legionId; string zoneName; // What part to advance to. Should be between 1-maxParts. uint8 advanceToPart; // The treasures to stake with the legion. uint256[] treasureIds; uint256[] treasureAmounts; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IAdvancedQuesting { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; interface IConsumable is IERC1155Upgradeable { function mint(address _to, uint256 _id, uint256 _amount) external; function burn(address account, uint256 id, uint256 value) external; function burnBatch(address account, uint256[] memory ids, uint256[] memory values) external; function adminSafeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) external; function adminSafeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITreasure { // Transfers the treasure at the given ID of the given amount. // Requires that the legions are pre-approved. // function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes memory data) external; // Transfers the treasure at the given ID of the given amount. // function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory data) external; // Admin only. // function mint(address _account, uint256 _tokenId, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; interface ILegion is IERC721MetadataUpgradeable { // Mints a legion to the given address. Returns the token ID. // Admin only. function safeMint(address _to) external returns(uint256); // Sets the URI for the given token id. Token must exist. // Admin only. function setTokenURI(uint256 _tokenId, string calldata _tokenURI) external; // Transfers the token to the given address. Does not need approval. _from still must be the owner of the token. // Admin only. function adminSafeTransferFrom(address _from, address _to, uint256 _tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./LegionMetadataStoreState.sol"; interface ILegionMetadataStore { // Sets the intial metadata for a token id. // Admin only. function setInitialMetadataForLegion(address _owner, uint256 _tokenId, LegionGeneration _generation, LegionClass _class, LegionRarity _rarity, uint256 _oldId) external; // Increases the quest level by one. It is up to the calling contract to regulate the max quest level. No validation. // Admin only. function increaseQuestLevel(uint256 _tokenId) external; // Increases the craft level by one. It is up to the calling contract to regulate the max craft level. No validation. // Admin only. function increaseCraftLevel(uint256 _tokenId) external; // Increases the rank of the given constellation to the given number. It is up to the calling contract to regulate the max constellation rank. No validation. // Admin only. function increaseConstellationRank(uint256 _tokenId, Constellation _constellation, uint8 _to) external; // Returns the metadata for the given legion. function metadataForLegion(uint256 _tokenId) external view returns(LegionMetadata memory); // Returns the tokenUri for the given token. function tokenURI(uint256 _tokenId) external view returns(string memory); } // As this will likely change in the future, this should not be used to store state, but rather // as parameters and return values from functions. struct LegionMetadata { LegionGeneration legionGeneration; LegionClass legionClass; LegionRarity legionRarity; uint8 questLevel; uint8 craftLevel; uint8[6] constellationRanks; uint256 oldId; } enum Constellation { FIRE, EARTH, WIND, WATER, LIGHT, DARK } enum LegionRarity { LEGENDARY, RARE, SPECIAL, UNCOMMON, COMMON, RECRUIT } enum LegionClass { RECRUIT, SIEGE, FIGHTER, ASSASSIN, RANGED, SPELLCASTER, RIVERMAN, NUMERAIRE, ALL_CLASS, ORIGIN } enum LegionGeneration { GENESIS, AUXILIARY, RECRUIT }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "../../shared/AdminableUpgradeable.sol"; import "./ILegionMetadataStore.sol"; abstract contract LegionMetadataStoreState is Initializable, AdminableUpgradeable { event LegionQuestLevelUp(uint256 indexed _tokenId, uint8 _questLevel); event LegionCraftLevelUp(uint256 indexed _tokenId, uint8 _craftLevel); event LegionConstellationRankUp(uint256 indexed _tokenId, Constellation indexed _constellation, uint8 _rank); event LegionCreated(address indexed _owner, uint256 indexed _tokenId, LegionGeneration _generation, LegionClass _class, LegionRarity _rarity); mapping(uint256 => LegionGeneration) internal idToGeneration; mapping(uint256 => LegionClass) internal idToClass; mapping(uint256 => LegionRarity) internal idToRarity; mapping(uint256 => uint256) internal idToOldId; mapping(uint256 => uint8) internal idToQuestLevel; mapping(uint256 => uint8) internal idToCraftLevel; mapping(uint256 => uint8[6]) internal idToConstellationRanks; mapping(LegionGeneration => mapping(LegionClass => mapping(LegionRarity => mapping(uint256 => string)))) internal _genToClassToRarityToOldIdToUri; function __LegionMetadataStoreState_init() internal initializer { AdminableUpgradeable.__Adminable_init(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IQuesting { function processQPGainAndLevelUp(uint256 _tokenId, uint8 _currentQuestLevel) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; interface ITreasureFragment is IERC1155Upgradeable { function mint(address _to, uint256 _id, uint256 _amount) external; function burn(address account, uint256 id, uint256 value) external; function burnBatch(address account, uint256[] memory ids, uint256[] memory values) external; function adminSafeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) external; function adminSafeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./TreasureMetadataStoreState.sol"; interface ITreasureMetadataStore { // Sets the metadata for the given Ids. // Admin only. function setMetadataForIds(uint256[] calldata _ids, TreasureMetadata[] calldata _metadatas) external; // Returns if the given ID has metadata set. function hasMetadataForTreasureId(uint256 _treasureId) external view returns(bool); // Returns the metadata for the given ID. Reverts if no metadata for the ID is set. function getMetadataForTreasureId(uint256 _treasureId) external view returns(TreasureMetadata memory); // For the given tier, gets a random MINTABLE treasure id. function getRandomTreasureForTier(uint8 _tier, uint256 _randomNumber) external view returns(uint256); // For the given tier AND category, gets a random MINTABLE treasure id. function getRandomTreasureForTierAndCategory( uint8 _tier, TreasureCategory _category, uint256 _randomNumber) external view returns(uint256); // For the given tier, gets a random treasure id, MINTABLE OR NOT. function getAnyRandomTreasureForTier(uint8 _tier, uint256 _randomNumber) external view returns(uint256); } // Do not change. Stored in state. struct TreasureMetadata { TreasureCategory category; uint8 tier; // Out of 100,000 uint32 craftingBreakOdds; bool isMintable; uint256 consumableIdDropWhenBreak; } enum TreasureCategory { ALCHEMY, ARCANA, BREWING, ENCHANTER, LEATHERWORKING, SMITHING }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../shared/AdminableUpgradeable.sol"; import "./ITreasureMetadataStore.sol"; import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; abstract contract TreasureMetadataStoreState is AdminableUpgradeable { mapping(uint8 => EnumerableSetUpgradeable.UintSet) internal tierToMintableTreasureIds; mapping(uint256 => TreasureMetadata) internal treasureIdToMetadata; mapping(uint8 => mapping(TreasureCategory => EnumerableSetUpgradeable.UintSet)) internal tierToCategoryToMintableTreasureIds; mapping(uint8 => EnumerableSetUpgradeable.UintSet) internal tierToTreasureIds; function __TreasureMetadataStoreState_init() internal initializer { AdminableUpgradeable.__Adminable_init(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../treasuremetadatastore/ITreasureMetadataStore.sol"; import "../legionmetadatastore/ILegionMetadataStore.sol"; interface ITreasureTriad { function generateBoardAndPlayGame( uint256 _randomNumber, LegionClass _legionClass, UserMove[] calldata _userMoves) external view returns(GameOutcome memory); } enum PlayerType { NONE, NATURE, USER } // Represents the information contained in a single cell of the game grid. struct GridCell { // The treasure played on this cell. May be 0 if PlayerType == NONE uint256 treasureId; // The type of player that has played on this cell. PlayerType playerType; // In the case that playerType == NATURE, if this is true, the player has flipped this card to their side. bool isFlipped; // Indicates if the cell is corrupted. // If the cell is empty, the player must place a card on it to make it uncorrupted. // If the cell has a contract/nature card, the player must flip the card to make it uncorrupted. bool isCorrupted; // Indicates if this cell has an affinity. If so, look at the affinity field. bool hasAffinity; // The affinity of this field. Only consider this field if hasAffinity is true. TreasureCategory affinity; } // Represents a move the end user will make. struct UserMove { // The x coordinate of the location uint8 x; // The y coordinate of the location. uint8 y; // The treasure to place at this location. uint256 treasureId; } struct GameOutcome { uint8 numberOfFlippedCards; uint8 numberOfCorruptedCardsLeft; bool playerWon; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./UtilitiesUpgradeable.sol"; // Do not add state to this contract. // contract AdminableUpgradeable is UtilitiesUpgradeable { mapping(address => bool) private admins; function __Adminable_init() internal initializer { UtilitiesUpgradeable.__Utilities__init(); } function addAdmin(address _address) external onlyOwner { admins[_address] = true; } function addAdmins(address[] calldata _addresses) external onlyOwner { for(uint256 i = 0; i < _addresses.length; i++) { admins[_addresses[i]] = true; } } function removeAdmin(address _address) external onlyOwner { admins[_address] = false; } function removeAdmins(address[] calldata _addresses) external onlyOwner { for(uint256 i = 0; i < _addresses.length; i++) { admins[_addresses[i]] = false; } } function setPause(bool _shouldPause) external onlyAdminOrOwner { if(_shouldPause) { _pause(); } else { _unpause(); } } function isAdmin(address _address) public view returns(bool) { return admins[_address]; } modifier onlyAdmin() { require(admins[msg.sender], "Not admin"); _; } modifier onlyAdminOrOwner() { require(admins[msg.sender] || isOwner(), "Not admin or owner"); _; } uint256[50] private __gap; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; contract UtilitiesUpgradeable is Initializable, OwnableUpgradeable, PausableUpgradeable { function __Utilities__init() internal initializer { OwnableUpgradeable.__Ownable_init(); PausableUpgradeable.__Pausable_init(); _pause(); } modifier nonZeroAddress(address _address) { require(address(0) != _address, "0 address"); _; } modifier nonZeroLength(uint[] memory _array) { require(_array.length > 0, "Empty array"); _; } modifier lengthsAreEqual(uint[] memory _array1, uint[] memory _array2) { require(_array1.length == _array2.length, "Unequal lengths"); _; } modifier onlyEOA() { /* solhint-disable avoid-tx-origin */ require(msg.sender == tx.origin, "No contracts"); _; } function isOwner() internal view returns(bool) { return owner() == msg.sender; } function compareStrings(string memory a, string memory b) internal pure returns (bool) { return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IRandomizer { // Sets the number of blocks that must pass between increment the commitId and seeding the random // Admin function setNumBlocksAfterIncrement(uint8 _numBlocksAfterIncrement) external; // Increments the commit id. // Admin function incrementCommitId() external; // Adding the random number needs to be done AFTER incrementing the commit id on a separate transaction. If // these are done together, there is a potential vulnerability to front load a commit when the bad actor // sees the value of the random number. function addRandomForCommit(uint256 _seed) external; // Returns a request ID for a random number. This is unique. function requestRandomNumber() external returns(uint256); // Returns the random number for the given request ID. Will revert // if the random is not ready. function revealRandomNumber(uint256 _requestId) external view returns(uint256); // Returns if the random number for the given request ID is ready or not. Call // before calling revealRandomNumber. function isRandomReady(uint256 _requestId) external view returns(bool); }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_legionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"_toPart","type":"uint8"}],"name":"AdvancedQuestContinued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_legionId","type":"uint256"},{"components":[{"internalType":"uint256","name":"consumableId","type":"uint256"},{"internalType":"uint256","name":"consumableAmount","type":"uint256"},{"internalType":"uint256","name":"treasureFragmentId","type":"uint256"},{"internalType":"uint256","name":"treasureId","type":"uint256"}],"indexed":false,"internalType":"struct AdvancedQuestingState.AdvancedQuestReward[]","name":"_rewards","type":"tuple[]"}],"name":"AdvancedQuestEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_requestId","type":"uint256"},{"components":[{"internalType":"uint256","name":"legionId","type":"uint256"},{"internalType":"string","name":"zoneName","type":"string"},{"internalType":"uint8","name":"advanceToPart","type":"uint8"},{"internalType":"uint256[]","name":"treasureIds","type":"uint256[]"},{"internalType":"uint256[]","name":"treasureAmounts","type":"uint256[]"}],"indexed":false,"internalType":"struct StartQuestParams","name":"_startQuestParams","type":"tuple"}],"name":"AdvancedQuestStarted","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_legionId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_playerWon","type":"bool"},{"indexed":false,"internalType":"uint8","name":"_numberOfCardsFlipped","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"_numberOfCorruptedCardsRemaining","type":"uint8"}],"name":"TreasureTriadPlayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_zoneName","type":"string"},{"components":[{"internalType":"uint256","name":"zoneStartTime","type":"uint256"},{"internalType":"enum TreasureCategory","name":"categoryBoost1","type":"uint8"},{"internalType":"enum TreasureCategory","name":"categoryBoost2","type":"uint8"},{"internalType":"enum Constellation","name":"constellation1","type":"uint8"},{"internalType":"enum Constellation","name":"constellation2","type":"uint8"},{"components":[{"internalType":"uint256","name":"zonePartLength","type":"uint256"},{"internalType":"uint256","name":"stasisLength","type":"uint256"},{"internalType":"uint8","name":"stasisBaseRate","type":"uint8"},{"internalType":"uint8","name":"questingLevelRequirement","type":"uint8"},{"internalType":"uint8","name":"questingXpGained","type":"uint8"},{"internalType":"bool","name":"playTreasureTriad","type":"bool"},{"components":[{"internalType":"uint8","name":"baseRateRewardOdds","type":"uint8"},{"internalType":"uint8[][]","name":"generationToRarityToBoost","type":"uint8[][]"},{"internalType":"uint8","name":"boostPerFlippedCard","type":"uint8"},{"components":[{"internalType":"uint256","name":"consumableId","type":"uint256"},{"internalType":"uint256","name":"consumableAmount","type":"uint256"},{"internalType":"uint256","name":"treasureFragmentId","type":"uint256"},{"internalType":"uint8","name":"treasureTier","type":"uint8"},{"internalType":"enum TreasureCategory","name":"treasureCategory","type":"uint8"},{"internalType":"uint8","name":"rewardOdds","type":"uint8"}],"internalType":"struct ZoneRewardOption[]","name":"rewardOptions","type":"tuple[]"}],"internalType":"struct ZoneReward[]","name":"rewards","type":"tuple[]"}],"internalType":"struct ZonePart[]","name":"parts","type":"tuple[]"}],"internalType":"struct ZoneInfo","name":"_zone","type":"tuple"}],"name":"addZone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_legionId","type":"uint256"}],"name":"advanceToPartForLegion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"areContractsSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"consumable","outputs":[{"internalType":"contract IConsumable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_legionIds","type":"uint256[]"}],"name":"continueAdvancedQuesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_legionId","type":"uint256"}],"name":"currentPartForLegion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_legionIds","type":"uint256[]"}],"name":"endQuesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_legionId","type":"uint256"}],"name":"endTimeForLegion","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_legionId","type":"uint256"}],"name":"isLegionQuesting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_zoneName","type":"string"}],"name":"isValidZone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legion","outputs":[{"internalType":"contract ILegion","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legionMetadataStore","outputs":[{"internalType":"contract ILegionMetadataStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_zoneName","type":"string"},{"internalType":"uint8","name":"_partIndex","type":"uint8"}],"name":"lengthForPartOfZone","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_zoneName","type":"string"}],"name":"numberOfPartsInZone","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_legionIds","type":"uint256[]"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint256","name":"treasureId","type":"uint256"}],"internalType":"struct UserMove[][]","name":"_playerMoves","type":"tuple[][]"},{"internalType":"bool[]","name":"_endQuestingAfterPlayingIfPossible","type":"bool[]"}],"name":"playTreasureTriad","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"questing","outputs":[{"internalType":"contract IQuesting","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomizer","outputs":[{"internalType":"contract IRandomizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"removeAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_randomizerAddress","type":"address"},{"internalType":"address","name":"_questingAddress","type":"address"},{"internalType":"address","name":"_legionAddress","type":"address"},{"internalType":"address","name":"_legionMetadataStoreAddress","type":"address"},{"internalType":"address","name":"_treasureAddress","type":"address"},{"internalType":"address","name":"_consumableAddress","type":"address"},{"internalType":"address","name":"_treasureMetadataStoreAddress","type":"address"},{"internalType":"address","name":"_treasureTriadAddress","type":"address"},{"internalType":"address","name":"_treasureFragmentAddress","type":"address"}],"name":"setContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_shouldPause","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stasisLengthForCorruptedCard","type":"uint256"}],"name":"setStasisLengthForCorruptedCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"legionId","type":"uint256"},{"internalType":"string","name":"zoneName","type":"string"},{"internalType":"uint8","name":"advanceToPart","type":"uint8"},{"internalType":"uint256[]","name":"treasureIds","type":"uint256[]"},{"internalType":"uint256[]","name":"treasureAmounts","type":"uint256[]"}],"internalType":"struct StartQuestParams[]","name":"_params","type":"tuple[]"}],"name":"startAdvancedQuesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stasisLengthForCorruptedCard","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasure","outputs":[{"internalType":"contract ITreasure","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasureFragment","outputs":[{"internalType":"contract ITreasureFragment","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasureMetadataStore","outputs":[{"internalType":"contract ITreasureMetadataStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasureTriad","outputs":[{"internalType":"contract ITreasureTriad","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_zoneName","type":"string"},{"internalType":"uint256[]","name":"_partLengths","type":"uint256[]"},{"internalType":"uint256[]","name":"_stasisLengths","type":"uint256[]"}],"name":"updatePartLengthsForZone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"zoneNameToInfo","outputs":[{"internalType":"uint256","name":"zoneStartTime","type":"uint256"},{"internalType":"enum TreasureCategory","name":"categoryBoost1","type":"uint8"},{"internalType":"enum TreasureCategory","name":"categoryBoost2","type":"uint8"},{"internalType":"enum Constellation","name":"constellation1","type":"uint8"},{"internalType":"enum Constellation","name":"constellation2","type":"uint8"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615f1c80620000216000396000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c80638129fc1c11610146578063bedb86fb116100c3578063d3f6760911610087578063d3f6760914610625578063d7dfe4dd14610639578063e520fc7e1461064d578063f10fb58414610661578063f23a6e6114610675578063f2fde38b1461069457600080fd5b8063bedb86fb146105ae578063c43c074c146105c1578063c87d4e07146105eb578063cedec2ff146105fe578063cfe519031461061157600080fd5b80639c54df641161010a5780639c54df6414610542578063a0122ec614610555578063a888306014610569578063abfe37b91461057c578063bc197c811461058f57600080fd5b80638129fc1c146104fa578063821cab0b146105025780638a7bf804146105155780638cdcc4b4146105295780638da5cb5b1461053157600080fd5b80633ea86bfe116101df57806370480275116101a3578063704802751461044b57806370e419451461045e578063715018a614610471578063790f20d9146104795780637ac290a8146104b95780637d7aa1bc146104e757600080fd5b80633ea86bfe1461039e578063452fd6d1146103b65780634bec7954146103c95780635c975abb1461042c578063675857eb1461043757600080fd5b80631b2378c5116102265780631b2378c51461031657806324d7806c146103295780632847a62d14610355578063377e11e0146103785780633c06ef4e1461038b57600080fd5b806301ffc9a7146102635780630a0e28d41461028b57806313bc0b8d146102a0578063150b7a02146102cc5780631785f53c14610303575b600080fd5b610276610271366004614411565b6106a7565b60405190151581526020015b60405180910390f35b61029e610299366004614486565b6106de565b005b610193546102b4906001600160a01b031681565b6040516001600160a01b039091168152602001610282565b6102ea6102da3660046145c8565b630a85bd0160e11b949350505050565b6040516001600160e01b03199091168152602001610282565b61029e61031136600461462f565b6107e6565b61027661032436600461468b565b610831565b61027661033736600461462f565b6001600160a01b031660009081526097602052604090205460ff1690565b6102766103633660046146c0565b600090815261019f6020526040902054151590565b61029e610386366004614486565b610860565b61029e6103993660046146c0565b610901565b6103a861019b5481565b604051908152602001610282565b6103a86103c436600461468b565b610944565b61041b6103d73660046146d9565b805160208183018101805161019c825292820191909301209152805460019091015460ff808216916101008104821691620100008204811691630100000090041685565b60405161028295949392919061474f565b60655460ff16610276565b610194546102b4906001600160a01b031681565b61029e61045936600461462f565b610974565b61029e61046c366004614486565b6109c2565b61029e610abb565b6104a76104873660046146c0565b600090815261019f6020526040902060080154600160a81b900460ff1690565b60405160ff9091168152602001610282565b6104a76104c73660046146c0565b600090815261019f6020526040902060080154600160a01b900460ff1690565b61029e6104f536600461479c565b610af1565b61029e610c97565b61029e610510366004614486565b610d11565b610195546102b4906001600160a01b031681565b610276610e0d565b6033546001600160a01b03166102b4565b61029e610550366004614486565b610edc565b610198546102b4906001600160a01b031681565b61029e610577366004614835565b610f78565b61029e61058a3660046148dd565b61105b565b6102ea61059d3660046149cb565b63bc197c8160e01b95945050505050565b61029e6105bc366004614a82565b611201565b6105d46105cf3660046146c0565b611254565b6040805192835260ff909116602083015201610282565b6103a86105f9366004614ab9565b611433565b61029e61060c366004614b04565b611488565b61019a546102b4906001600160a01b031681565b610199546102b4906001600160a01b031681565b610197546102b4906001600160a01b031681565b610196546102b4906001600160a01b031681565b610192546102b4906001600160a01b031681565b6102ea610683366004614b40565b63f23a6e6160e01b95945050505050565b61029e6106a236600461462f565b611626565b60006001600160e01b03198216630271189760e51b14806106d857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60655460ff161561070a5760405162461bcd60e51b815260040161070190614ba4565b60405180910390fd5b610712610e0d565b61072e5760405162461bcd60e51b815260040161070190614bce565b33321461074d5760405162461bcd60e51b815260040161070190614bfc565b818180806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508251151591506107a290505760405162461bcd60e51b815260040161070190614c22565b60005b828110156107e0576107ce8484838181106107c2576107c2614c47565b905060200201356116be565b806107d881614c73565b9150506107a5565b50505050565b6033546001600160a01b031633146108105760405162461bcd60e51b815260040161070190614c8e565b6001600160a01b03166000908152609760205260409020805460ff19169055565b60008061019c8484604051610847929190614cc3565b9081526040519081900360200190205411905092915050565b6033546001600160a01b0316331461088a5760405162461bcd60e51b815260040161070190614c8e565b60005b818110156108fc576000609760008585858181106108ad576108ad614c47565b90506020020160208101906108c2919061462f565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806108f481614c73565b91505061088d565b505050565b3360009081526097602052604090205460ff16806109225750610922611b14565b61093e5760405162461bcd60e51b815260040161070190614cd3565b61019b55565b600061019c8383604051610959929190614cc3565b90815260405190819003602001902060020154905092915050565b6033546001600160a01b0316331461099e5760405162461bcd60e51b815260040161070190614c8e565b6001600160a01b03166000908152609760205260409020805460ff19166001179055565b60655460ff16156109e55760405162461bcd60e51b815260040161070190614ba4565b6109ed610e0d565b610a095760405162461bcd60e51b815260040161070190614bce565b333214610a285760405162461bcd60e51b815260040161070190614bfc565b81818080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050825115159150610a7d90505760405162461bcd60e51b815260040161070190614c22565b60005b828110156107e057610aa9848483818110610a9d57610a9d614c47565b90506020020135611b38565b80610ab381614c73565b915050610a80565b6033546001600160a01b03163314610ae55760405162461bcd60e51b815260040161070190614c8e565b610aef6000611cd0565b565b3360009081526097602052604090205460ff1680610b125750610b12611b14565b610b2e5760405162461bcd60e51b815260040161070190614cd3565b610b388686610831565b610b765760405162461bcd60e51b815260206004820152600f60248201526e169bdb99481a5cc81a5b9d985b1a59608a1b6044820152606401610701565b600061019c8787604051610b8b929190614cc3565b908152604051908190036020019020600281015490915084148015610baf57508382145b610bef5760405162461bcd60e51b8152602060048201526011602482015270426164206172726179206c656e6774687360781b6044820152606401610701565b60005b84811015610c8d57858582818110610c0c57610c0c614c47565b90506020020135826002018281548110610c2857610c28614c47565b6000918252602090912060049091020155838382818110610c4b57610c4b614c47565b90506020020135826002018281548110610c6757610c67614c47565b600091825260209091206001600490920201015580610c8581614c73565b915050610bf2565b5050505050505050565b600054610100900460ff16610cb25760005460ff1615610cb6565b303b155b610cd25760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015610cf4576000805461ffff19166101011790555b610cfc611d22565b8015610d0e576000805461ff00191690555b50565b60655460ff1615610d345760405162461bcd60e51b815260040161070190614ba4565b610d3c610e0d565b610d585760405162461bcd60e51b815260040161070190614bce565b333214610d775760405162461bcd60e51b815260040161070190614bfc565b80610dc45760405162461bcd60e51b815260206004820152601b60248201527f4e6f20737461727420717565737420706172616d7320676976656e00000000006044820152606401610701565b60005b818110156108fc57610dfb838383818110610de457610de4614c47565b9050602002810190610df69190614d4d565b611d87565b80610e0581614c73565b915050610dc7565b610192546000906001600160a01b031615801590610e365750610193546001600160a01b031615155b8015610e4d5750610194546001600160a01b031615155b8015610e645750610195546001600160a01b031615155b8015610e7b5750610196546001600160a01b031615155b8015610e925750610197546001600160a01b031615155b8015610ea95750610198546001600160a01b031615155b8015610ec05750610199546001600160a01b031615155b8015610ed7575061019a546001600160a01b031615155b905090565b6033546001600160a01b03163314610f065760405162461bcd60e51b815260040161070190614c8e565b60005b818110156108fc57600160976000858585818110610f2957610f29614c47565b9050602002016020810190610f3e919061462f565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610f7081614c73565b915050610f09565b3360009081526097602052604090205460ff1680610f995750610f99611b14565b610fb55760405162461bcd60e51b815260040161070190614cd3565b61019280546001600160a01b03199081166001600160a01b039b8c161790915561019380548216998b169990991790985561019480548916978a16979097179096556101958054881695891695909517909455610196805487169388169390931790925561019780548616918716919091179055610198805485169186169190911790556101998054841691851691909117905561019a80549092169216919091179055565b3360009081526097602052604090205460ff168061107c575061107c611b14565b6110985760405162461bcd60e51b815260040161070190614cd3565b6110e583838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506127bb915050565b156111325760405162461bcd60e51b815260206004820152601960248201527f5a6f6e65206e616d652063616e6e6f7420626520626c616e6b000000000000006044820152606401610701565b61113c8383610831565b1561117f5760405162461bcd60e51b81526020600482015260136024820152725a6f6e6520616c72656164792065786973747360681b6044820152606401610701565b80356111cd5760405162461bcd60e51b815260206004820152601b60248201527f5a6f6e65206d757374206861766520612073746172742074696d6500000000006044820152606401610701565b8061019c84846040516111e1929190614cc3565b9081526040519081900360200190206111fa8282615449565b5050505050565b3360009081526097602052604090205460ff16806112225750611222611b14565b61123e5760405162461bcd60e51b815260040161070190614cd3565b801561124c57610d0e612814565b610d0e612889565b610195546040516378afdef960e11b815260048101839052600091829182916001600160a01b03169063f15fbdf2906024016101806040518083038186803b15801561129f57600080fd5b505afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d7919061568d565b9050600061138461019f6000878152602001908152602001600020600701805461130090615722565b80601f016020809104026020016040519081016040528092919081815260200182805461132c90615722565b80156113795780601f1061134e57610100808354040283529160200191611379565b820191906000526020600020905b81548152906001019060200180831161135c57829003601f168201915b505050505083612903565b61019254600087815261019f6020526040808220600101549051634ad30a7560e01b81526004810191909152929350916001600160a01b0390911690634ad30a759060240160206040518083038186803b1580156113e157600080fd5b505afa1580156113f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611419919061575d565b9050611427868484846129de565b94509450505050915091565b600061019c8484604051611448929190614cc3565b90815260200160405180910390206002018260ff168154811061146d5761146d614c47565b90600052602060002090600402016000015490509392505050565b60655460ff16156114ab5760405162461bcd60e51b815260040161070190614ba4565b6114b3610e0d565b6114cf5760405162461bcd60e51b815260040161070190614bce565b3332146114ee5760405162461bcd60e51b815260040161070190614bfc565b8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505082511515915061154390505760405162461bcd60e51b815260040161070190614c22565b858414801561155157508582145b61159d5760405162461bcd60e51b815260206004820152601a60248201527f426164206172726179206c656e6774687320666f7220706c61790000000000006044820152606401610701565b60005b86811015610c8d576116148888838181106115bd576115bd614c47565b905060200201358787848181106115d6576115d6614c47565b90506020028101906115e89190615776565b8787868181106115fa576115fa614c47565b905060200201602081019061160f9190614a82565b612cb5565b8061161e81614c73565b9150506115a0565b6033546001600160a01b031633146116505760405162461bcd60e51b815260040161070190614c8e565b6001600160a01b0381166116b55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610701565b610d0e81611cd0565b600081815261019f60205260408082206101955491516378afdef960e11b8152600481018590529092916001600160a01b03169063f15fbdf2906024016101806040518083038186803b15801561171457600080fd5b505afa158015611728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174c919061568d565b9050600061019c8360070160405161176491906157be565b90815260405190819003602001902060088401549091506001600160a01b031633146117a25760405162461bcd60e51b81526004016107019061585a565b61019254600085815261019f6020526040808220600101549051634ad30a7560e01b815291926001600160a01b031691634ad30a75916117e89160040190815260200190565b60206040518083038186803b15801561180057600080fd5b505afa158015611814573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611838919061575d565b905061184985858585856001612f89565b6002820154600885015461186890600160a01b900460ff166001615887565b60ff1611156118b05760405162461bcd60e51b8152602060048201526014602482015273105b1c9958591e48185d081b185cdd081c185c9d60621b6044820152606401610701565b60088401546002830180549091600160a01b900460ff169081106118d6576118d6614c47565b6000918252602090912060026004909202010154606084015160ff6101009092048216911610156119195760405162461bcd60e51b8152600401610701906158ac565b60088401546002830180549091600160a01b900460ff1690811061193f5761193f614c47565b906000526020600020906004020160020160039054906101000a900460ff161580611975575060006119738560040161316b565b115b6119c15760405162461bcd60e51b815260206004820152601d60248201527f4e6f207472656173757265207374616b656420666f72206c6567696f6e0000006044820152606401610701565b610192546040805163433c53d960e11b815290516000926001600160a01b031691638678a7b291600480830192602092919082900301818787803b158015611a0857600080fd5b505af1158015611a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a40919061575d565b42865560088601805460ff60a81b198116600160a01b9182900460ff908116600160a81b02919091178084559394509204909116906014611a80836158f1565b82546101009290920a60ff8181021990931691831602179091556000600288015560038701805461ffff1916905560018701839055600887015460408051338152602081018b9052908101859052600160a01b90910490911660608201527f6637022d9de6a2060f00e17833969643de3940f9fc4ea37f4e755ae5121b13c3915060800160405180910390a1505050505050565b600033611b296033546001600160a01b031690565b6001600160a01b031614905090565b600081815261019f60205260408082206101955491516378afdef960e11b8152600481018590529092916001600160a01b03169063f15fbdf2906024016101806040518083038186803b158015611b8e57600080fd5b505afa158015611ba2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc6919061568d565b9050600061019c83600701604051611bde91906157be565b90815260405190819003602001902060088401549091506001600160a01b03163314611c1c5760405162461bcd60e51b81526004016107019061585a565b61019254600085815261019f6020526040808220600101549051634ad30a7560e01b815291926001600160a01b031691634ad30a7591611c629160040190815260200190565b60206040518083038186803b158015611c7a57600080fd5b505afa158015611c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb2919061575d565b9050611cc385858585856001612f89565b6111fa8585858585613175565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611d3d5760005460ff1615611d41565b303b155b611d5d5760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015611d7f576000805461ffff19166101011790555b610cfc6133f7565b8035600081815261019f602052604090205415611de65760405162461bcd60e51b815260206004820152601a60248201527f4c6567696f6e20697320616c7265616479207175657374696e670000000000006044820152606401610701565b611df66103246020840184615911565b611e315760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207a6f6e6560a01b6044820152606401610701565b6000611e436103c46020850185615911565b90506000611e576060850160408601615957565b60ff16118015611e79575080611e736060850160408601615957565b60ff1611155b611ec55760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420616476616e636520746f20706172740000000000000000006044820152606401610701565b610195546040516378afdef960e11b8152600481018490526000916001600160a01b03169063f15fbdf2906024016101806040518083038186803b158015611f0c57600080fd5b505afa158015611f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f44919061568d565b9050600281516002811115611f5b57611f5b614729565b1415611fa95760405162461bcd60e51b815260206004820152601d60248201527f526563727569742063616e6e6f7420616476616e6365642071756573740000006044820152606401610701565b6000805b611fbd6060870160408801615957565b60ff1681101561216e57600061019c611fd96020890189615911565b604051611fe7929190614cc3565b9081526020016040518091039020600201828154811061200957612009614c47565b6000918252602090912060026004909202010154606085015160ff610100909204821692501681111561204e5760405162461bcd60e51b8152600401610701906158ac565b600061019c61206060208a018a615911565b60405161206e929190614cc3565b9081526020016040518091039020600201838154811061209057612090614c47565b906000526020600020906004020160020160039054906101000a900460ff16905083806120ba5750805b935060016120ce60608a0160408b01615957565b6120d89190615974565b60ff16831080156120e65750805b156121595760405162461bcd60e51b815260206004820152603860248201527f43616e6e6f7420616476616e636564207061737420612070617274207468617460448201527f20726571756972657320747265617375726520747269616400000000000000006064820152608401610701565b5050808061216690614c73565b915050611fad565b5061217c6080860186614d7a565b905061218b6060870187614d7a565b9050146121d15760405162461bcd60e51b8152602060048201526014602482015273426164207472656173757265206c656e6774687360601b6044820152606401610701565b8015806121ec575060006121e86060870187614d7a565b9050115b6122445760405162461bcd60e51b8152602060048201526024808201527f4e65656420747265617375726520746f20706c617920747265617375726520746044820152631c9a585960e21b6064820152608401610701565b6000806122936122576020890189615911565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250612903915050565b905060005b6122a56060890189614d7a565b90508110156123f85760006122bd60608a018a614d7a565b838181106122cd576122cd614c47565b90506020020135118015612304575060006122eb60808a018a614d7a565b838181106122fb576122fb614c47565b90506020020135115b6123505760405162461bcd60e51b815260206004820152601960248201527f426164207472656173757265206964206f7220616d6f756e74000000000000006044820152606401610701565b61235d6080890189614d7a565b8281811061236d5761236d614c47565b905060200201358361237f9190615997565b92508160ff168311156123e65760405162461bcd60e51b815260206004820152602960248201527f546f6f206d616e792074726561737572657320666f7220636f6e7374656c6c6160448201526874696f6e2072616e6b60b81b6064820152608401610701565b806123f081614c73565b915050612298565b50610192546040805163433c53d960e11b815290516000926001600160a01b031691638678a7b291600480830192602092919082900301818787803b15801561244057600080fd5b505af1158015612454573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612478919061575d565b600088815261019f602090815260409091204281556001018290559091506124a290890189615911565b600089815261019f602052604090206124c092600790910191614378565b50600087815261019f60205260409081902060080180546001600160a01b031916331790556124f59060608a01908a01615957565b600088815261019f6020526040812060088101805461ffff60a01b1916600160a01b60ff959095169490940260ff60a81b191693909317909255600282018190556003909101805461ffff191690555b61255260608a018a614d7a565b905081101561266f57600061256a60608b018b614d7a565b8381811061257a5761257a614c47565b9050602002013590506125ac8161019f60008c815260200190815260200160002060040161345c90919063ffffffff16565b156125f95760405162461bcd60e51b815260206004820152601e60248201527f4475706c696361746520747265617375726520696420696e20617272617900006044820152606401610701565b600089815261019f602052604090206126159060040182613477565b5061262360808b018b614d7a565b8381811061263357612633614c47565b60008c815261019f602090815260408083209683526006909601815294902093029190910135909155508061266781614c73565b915050612545565b50610194546040516383291f8760e01b8152336004820152306024820152604481018990526001600160a01b03909116906383291f8790606401600060405180830381600087803b1580156126c357600080fd5b505af11580156126d7573d6000803e3d6000fd5b50600092506126ec91505060608a018a614d7a565b9050111561277657610196546001600160a01b0316632eb2c2d6333061271560608d018d614d7a565b61272260808f018f614d7a565b6040518763ffffffff1660e01b8152600401612743969594939291906159e5565b600060405180830381600087803b15801561275d57600080fd5b505af1158015612771573d6000803e3d6000fd5b505050505b7f6c0d8f3939be2a5b9dcf5ce392c338774f1e1fce2cfa6a61a9ad81ad1dd3dd1933828a6040516127a993929190615ab5565b60405180910390a15050505050505050565b6000816040516020016127ce9190615b9e565b60405160208183030381529060405280519060200120836040516020016127f59190615b9e565b6040516020818303038152906040528051906020012014905092915050565b60655460ff16156128375760405162461bcd60e51b815260040161070190614ba4565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861286c3390565b6040516001600160a01b03909116815260200160405180910390a1565b60655460ff166128d25760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610701565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361286c565b6000808260a0015161019c8560405161291c9190615b9e565b9081526040519081900360200190206001015460ff6201000090910416600581111561294a5761294a614729565b6006811061295a5761295a614c47565b6020020151905060008360a0015161019c866040516129799190615b9e565b9081526040519081900360200190206001015460ff63010000009091041660058111156129a8576129a8614729565b600681106129b8576129b8614c47565b602002015190508060ff168260ff1611156129d5575090506106d8565b91506106d89050565b600084815261019f60205260408120548190612a355760405162461bcd60e51b81526020600482015260166024820152754c6567696f6e206973206e6f74207175657374696e6760501b6044820152606401610701565b600086815261019f6020526040808220905190919061019c90612a5c9060078501906157be565b90815260405190819003602001902060028084015460038501546008860154939450909260ff91821692850191612a9e91600191600160a01b90910416615974565b60ff1681548110612ab157612ab1614c47565b906000526020600020906004020160020160039054906101000a900460ff168015612adc5750600082115b8015612ae85750600081115b15612b125761019b54612afb9082614dd9565b612b059083615997565b95509350612cac92505050565b60ff808916600090815261019e602052604081205460088701549192908116918391600160a81b909104165b6008880154600160a01b900460ff16811015612c8557866002018181548110612b6957612b69614c47565b90600052602060002090600402016000015484612b869190615997565b935061019d60008e600001516002811115612ba357612ba3614729565b6002811115612bb457612bb4614729565b815260208101919091526040016000205460ff1615612c73576000876002018281548110612be457612be4614c47565b600091825260209091206002600490920201015460ff90811691508416811115612c7157612c128482615974565b60ff16612c216101008e615bd9565b1015612c695782612c31816158f1565b935050876002018281548110612c4957612c49614c47565b90600052602060002090600402016001015485612c669190615997565b94505b60088c901c9b505b505b80612c7d81614c73565b915050612b3e565b5060008d815261019f6020526040902054612ca1908490615997565b985096505050505050505b94509492505050565b600084815261019f60205260408082206101955491516378afdef960e11b8152600481018890529092916001600160a01b03169063f15fbdf2906024016101806040518083038186803b158015612d0b57600080fd5b505afa158015612d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d43919061568d565b9050600061019c83600701604051612d5b91906157be565b90815260405190819003602001902060088401549091506001600160a01b03163314612d995760405162461bcd60e51b81526004016107019061585a565b61019254600088815261019f6020526040808220600101549051634ad30a7560e01b815291926001600160a01b031691634ad30a7591612ddf9160040190815260200190565b60206040518083038186803b158015612df757600080fd5b505afa158015612e0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2f919061575d565b9050612e4088858585856000612f89565b612e4b878786613483565b6101995460208401516040516330019d4b60e01b81526000926001600160a01b0316916330019d4b91612e869186918d908d90600401615bfb565b60606040518083038186803b158015612e9e57600080fd5b505afa158015612eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed69190615c86565b426002870155602081810151600388018054845160ff93841661ffff199092168217610100949091169384021790915560408085015181513381529485018f9052151590840152606083019190915260808201529091507f9cc74f6243b89778b7e86d5b933c4146bd93203932a12bfe7ad7625d433e67ae9060a00160405180910390a1858015612f6c5750602081015160ff16155b15612f7e57612f7e8986868686613175565b505050505050505050565b6000613021866007018054612f9d90615722565b80601f0160208091040260200160405190810160405280929190818152602001828054612fc990615722565b80156130165780601f10612feb57610100808354040283529160200191613016565b820191906000526020600020905b815481529060010190602001808311612ff957829003601f168201915b505050505086612903565b90506000613031888784876129de565b5090508042101561309e5760405162461bcd60e51b815260206004820152603160248201527f4c6567696f6e20686173206e6f742066696e69736865642074686973207061726044820152701d081bd9881d1a19481e9bdb99481e595d607a1b6064820152608401610701565b8280156130f95750600887015460028601906130c690600190600160a01b900460ff16615974565b60ff16815481106130d9576130d9614c47565b906000526020600020906004020160020160039054906101000a900460ff165b801561310757506002870154155b15610c8d5760405162461bcd60e51b815260206004820152602e60248201527f486173206e6f7420706c6179656420747265617375726520747269616420666f60448201526d1c8818dd5c9c995b9d081c185c9d60921b6064820152608401610701565b60006106d8825490565b610193546060840151604051632fb44d2760e11b81526004810188905260ff90911660248201526001600160a01b0390911690635f689a4e90604401600060405180830381600087803b1580156131cb57600080fd5b505af11580156131df573d6000803e3d6000fd5b5050505060006131f185858585613768565b60008655610194546040516383291f8760e01b8152306004820152336024820152604481018990529192506001600160a01b0316906383291f8790606401600060405180830381600087803b15801561324957600080fd5b505af115801561325d573d6000803e3d6000fd5b50505050600061326f86600401613cce565b9050600081516001600160401b0381111561328c5761328c6144e3565b6040519080825280602002602001820160405280156132b5578160200160208202803683370190505b50905060005b8251811015613352576132f38382815181106132d9576132d9614c47565b602002602001015189600401613cdb90919063ffffffff16565b5087600601600084838151811061330c5761330c614c47565b602002602001015181526020019081526020016000205482828151811061333557613335614c47565b60209081029190910101528061334a81614c73565b9150506132bb565b508151156133c45761019654604051631759616b60e11b81526001600160a01b0390911690632eb2c2d690613391903090339087908790600401615d32565b600060405180830381600087803b1580156133ab57600080fd5b505af11580156133bf573d6000803e3d6000fd5b505050505b7f9949f99e59b9a76e12491767b7369cea6085b2e0f953d867d6a20484c12b105c3389856040516127a993929190615d8d565b600054610100900460ff166134125760005460ff1615613416565b303b155b6134325760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015613454576000805461ffff19166101011790555b610cfc613ce7565b600081815260018301602052604081205415155b9392505050565b60006134708383613f02565b81158015906134925750600482105b6134e95760405162461bcd60e51b815260206004820152602260248201527f426164206e756d626572206f66207472656173757265207472696164206d6f76604482015261657360f01b6064820152608401610701565b6000826001600160401b03811115613503576135036144e3565b60405190808252806020026020018201604052801561354857816020015b60408051808201909152600080825260208201528152602001906001900390816135215790505b5090506000805b8481101561376057600086868381811061356b5761356b614c47565b90506060020160400135905061358d818660040161345c90919063ffffffff16565b6135ea5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420706c6179207472656173757265207468617420776173206e6f6044820152671d081cdd185ad95960c21b6064820152608401610701565b6000805b85518110156136e3578286828151811061360a5761360a614c47565b60200260200101516000015114156136d1576001915085818151811061363257613632614c47565b6020026020010151602001516000141561369e5760405162461bcd60e51b815260206004820152602760248201527f55736564206d6f7265207472656173757265207468616e207768617420776173604482015266081cdd185ad95960ca1b6064820152608401610701565b8581815181106136b0576136b0614c47565b602002602001015160200180518091906136c990615e0a565b9052506136e3565b806136db81614c73565b9150506135ee565b508061374b57604051806040016040528083815260200160018860060160008681526020019081526020016000205461371c9190615e21565b81525085858151811061373157613731614c47565b6020026020010181905250838061374790614c73565b9450505b5050808061375890614c73565b91505061354f565b505050505050565b606060008360020160018760080160149054906101000a900460ff1661378e9190615974565b60ff16815481106137a1576137a1614c47565b90600052602060002090600402019050827f270403fba6eda13e1a219e01f1fb9cac4267cb529255cf0cb111921f931242186040516020016137ed929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c925060008560000151600281111561382057613820614729565b905060008660400151600581111561383a5761383a614729565b60038401549091506000906001600160401b0381111561385c5761385c6144e3565b6040519080825280602002602001820160405280156138b857816020015b6138a56040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020019060019003908161387a5790505b50905060005b6003850154811015613cc15760008560030182815481106138e1576138e1614c47565b60009182526020822060038e015460049290920201600281015490935061391391610100900460ff9081169116615e38565b82600101878154811061392857613928614c47565b90600052602060002001868154811061394357613943614c47565b600091825260209182902091810490910154845461397192601f166101000a90910460ff9081169116615887565b61397b9190615887565b60ff169050600060ff8210613992575060016139b7565b81156139b757816139a56101008c615bd9565b10156139af575060015b60088a901c99505b8015613cab5760006139c98b85613f51565b8054909150158015906139e0575060008160010154115b15613aa45780600001548686815181106139fc576139fc614c47565b602002602001015160000181815250508060010154868681518110613a2357613a23614c47565b60209081029190910181015101526101975481546001830154604051630ab714fb60e11b8152336004820152602481019290925260448201526001600160a01b039091169063156e29f690606401600060405180830381600087803b158015613a8b57600080fd5b505af1158015613a9f573d6000803e3d6000fd5b505050505b600281015415613b49578060020154868681518110613ac557613ac5614c47565b602090810291909101015160409081019190915261019a5460028301549151630ab714fb60e11b81523360048201526024810192909252600160448301526001600160a01b03169063156e29f690606401600060405180830381600087803b158015613b3057600080fd5b505af1158015613b44573d6000803e3d6000fd5b505050505b600381015460ff1615613ca257600061019860009054906101000a90046001600160a01b03166001600160a01b031663580364e08360030160009054906101000a900460ff168460030160019054906101000a900460ff168f6040518463ffffffff1660e01b8152600401613bc093929190615e61565b60206040518083038186803b158015613bd857600080fd5b505afa158015613bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c10919061575d565b905080878781518110613c2557613c25614c47565b60209081029190910101516060015261019654604051630ab714fb60e11b815233600482015260248101839052600160448201526001600160a01b039091169063156e29f690606401600060405180830381600087803b158015613c8857600080fd5b505af1158015613c9c573d6000803e3d6000fd5b50505050505b60088b901c9a50505b5050508080613cb990614c73565b9150506138be565b5098975050505050505050565b6060600061347083614067565b600061347083836140c3565b600054610100900460ff16613d025760005460ff1615613d06565b303b155b613d225760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015613d44576000805461ffff19166101011790555b613d4c6141b6565b613d5461421b565b613d5c61421b565b6201518061019b557f13dcb3c6205eccc5df5a4a7821d488c75d9d361908855b59d022fe13c7bb4f1d805460ff199081169091557f228719b3ab53201bbb41968c40b0b5cdf287f8c98ba3ec9532f722219a6d86ff80548216600117905561019e6020527f2d695d1bdc89be0990c9b1cefd0e589f7fbb3368bfb8d91126956a95dcf1607380548216600a1790557f1482f8fde77c2e0a1223b839dd85e5e0d40575a23bb6b13896f241a0b36fe0d880548216600f1790557f819c8b3e70c1a841f15170a81b2fad3b9dd6363490e4d79d5e443edaf01bbd658054821660141790557ff166615731f9a0da5f995c890da9823aee980021e1f67a3a50824b9391ea855f8054821660171790557f5fc73781db4fef9135a7751bb16b9dc0cf5d8f49924b6290e697d3ce5362e55b8054821660261790557f0c0534c4fd269d874c4e3ccf61cdfc386596ea47184f1d857725cfeaab13fd5080548216603317905560076000527f52fc7babecae6ce4e4dc8870a20313c060d91987e43bc7d10bf81d0e02b5bebc8054604092169190911790558015610d0e576000805461ff001916905550565b6000818152600183016020526040812054613f49575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106d8565b5060006106d8565b600381015460009060011415613f8c5781600301600081548110613f7757613f77614c47565b906000526020600020906004020190506106d8565b6000613f9a61010085615bd9565b90506000600885901c945060005b600385015481101561401e576000856003018281548110613fcb57613fcb614c47565b600091825260209091206004909102016003810154909150613ff69062010000900460ff1684615997565b92508284101561400b5793506106d892505050565b508061401681614c73565b915050613fa8565b5060405162461bcd60e51b815260206004820152601860248201527f426164206f64647320666f72207a6f6e652072657761726400000000000000006044820152606401610701565b6060816000018054806020026020016040519081016040528092919081815260200182805480156140b757602002820191906000526020600020905b8154815260200190600101908083116140a3575b50505050509050919050565b600081815260018301602052604081205480156141ac5760006140e7600183615e21565b85549091506000906140fb90600190615e21565b905081811461416057600086600001828154811061411b5761411b614c47565b906000526020600020015490508087600001848154811061413e5761413e614c47565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061417157614171615e85565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106d8565b60009150506106d8565b600054610100900460ff166141d15760005460ff16156141d5565b303b155b6141f15760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015614213576000805461ffff19166101011790555b610cfc614242565b600054610100900460ff16610aef5760405162461bcd60e51b815260040161070190615e9b565b600054610100900460ff1661425d5760005460ff1615614261565b303b155b61427d5760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff1615801561429f576000805461ffff19166101011790555b6142a76142b7565b6142af6142e6565b610cfc612814565b600054610100900460ff166142de5760405162461bcd60e51b815260040161070190615e9b565b610aef614315565b600054610100900460ff1661430d5760405162461bcd60e51b815260040161070190615e9b565b610aef614345565b600054610100900460ff1661433c5760405162461bcd60e51b815260040161070190615e9b565b610aef33611cd0565b600054610100900460ff1661436c5760405162461bcd60e51b815260040161070190615e9b565b6065805460ff19169055565b82805461438490615722565b90600052602060002090601f0160209004810192826143a657600085556143ec565b82601f106143bf5782800160ff198235161785556143ec565b828001600101855582156143ec579182015b828111156143ec5782358255916020019190600101906143d1565b506143f89291506143fc565b5090565b5b808211156143f857600081556001016143fd565b60006020828403121561442357600080fd5b81356001600160e01b03198116811461347057600080fd5b60008083601f84011261444d57600080fd5b5081356001600160401b0381111561446457600080fd5b6020830191508360208260051b850101111561447f57600080fd5b9250929050565b6000806020838503121561449957600080fd5b82356001600160401b038111156144af57600080fd5b6144bb8582860161443b565b90969095509350505050565b80356001600160a01b03811681146144de57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561451b5761451b6144e3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614549576145496144e3565b604052919050565b60006001600160401b0383111561456a5761456a6144e3565b61457d601f8401601f1916602001614521565b905082815283838301111561459157600080fd5b828260208301376000602084830101529392505050565b600082601f8301126145b957600080fd5b61347083833560208501614551565b600080600080608085870312156145de57600080fd5b6145e7856144c7565b93506145f5602086016144c7565b92506040850135915060608501356001600160401b0381111561461757600080fd5b614623878288016145a8565b91505092959194509250565b60006020828403121561464157600080fd5b613470826144c7565b60008083601f84011261465c57600080fd5b5081356001600160401b0381111561467357600080fd5b60208301915083602082850101111561447f57600080fd5b6000806020838503121561469e57600080fd5b82356001600160401b038111156146b457600080fd5b6144bb8582860161464a565b6000602082840312156146d257600080fd5b5035919050565b6000602082840312156146eb57600080fd5b81356001600160401b0381111561470157600080fd5b8201601f8101841361471257600080fd5b61472184823560208401614551565b949350505050565b634e487b7160e01b600052602160045260246000fd5b60068110610d0e57610d0e614729565b85815260a0810161475f8661473f565b85602083015261476e8561473f565b84604083015261477d8461473f565b83606083015261478c8361473f565b8260808301529695505050505050565b600080600080600080606087890312156147b557600080fd5b86356001600160401b03808211156147cc57600080fd5b6147d88a838b0161464a565b909850965060208901359150808211156147f157600080fd5b6147fd8a838b0161443b565b9096509450604089013591508082111561481657600080fd5b5061482389828a0161443b565b979a9699509497509295939492505050565b60008060008060008060008060006101208a8c03121561485457600080fd5b61485d8a6144c7565b985061486b60208b016144c7565b975061487960408b016144c7565b965061488760608b016144c7565b955061489560808b016144c7565b94506148a360a08b016144c7565b93506148b160c08b016144c7565b92506148bf60e08b016144c7565b91506148ce6101008b016144c7565b90509295985092959850929598565b6000806000604084860312156148f257600080fd5b83356001600160401b038082111561490957600080fd5b6149158783880161464a565b9095509350602086013591508082111561492e57600080fd5b50840160c0818703121561494157600080fd5b809150509250925092565b600082601f83011261495d57600080fd5b813560206001600160401b03821115614978576149786144e3565b8160051b614987828201614521565b92835284810182019282810190878511156149a157600080fd5b83870192505b848310156149c0578235825291830191908301906149a7565b979650505050505050565b600080600080600060a086880312156149e357600080fd5b6149ec866144c7565b94506149fa602087016144c7565b935060408601356001600160401b0380821115614a1657600080fd5b614a2289838a0161494c565b94506060880135915080821115614a3857600080fd5b614a4489838a0161494c565b93506080880135915080821115614a5a57600080fd5b50614a67888289016145a8565b9150509295509295909350565b8015158114610d0e57600080fd5b600060208284031215614a9457600080fd5b813561347081614a74565b60ff81168114610d0e57600080fd5b80356144de81614a9f565b600080600060408486031215614ace57600080fd5b83356001600160401b03811115614ae457600080fd5b614af08682870161464a565b909450925050602084013561494181614a9f565b60008060008060008060608789031215614b1d57600080fd5b86356001600160401b0380821115614b3457600080fd5b6147d88a838b0161443b565b600080600080600060a08688031215614b5857600080fd5b614b61866144c7565b9450614b6f602087016144c7565b9350604086013592506060860135915060808601356001600160401b03811115614b9857600080fd5b614a67888289016145a8565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60208082526014908201527310dbdb9d1c9858dd1cc8185c995b89dd081cd95d60621b604082015260600190565b6020808252600c908201526b4e6f20636f6e74726163747360a01b604082015260600190565b6020808252600b908201526a456d70747920617272617960a81b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614c8757614c87614c5d565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b8183823760009101908152919050565b6020808252601290820152712737ba1030b236b4b71037b91037bbb732b960711b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60008235609e19833603018112614d6357600080fd5b9190910192915050565b60068110610d0e57600080fd5b6000808335601e19843603018112614d9157600080fd5b8301803591506001600160401b03821115614dab57600080fd5b6020019150600581901b360382131561447f57600080fd5b6000823560de19833603018112614d6357600080fd5b6000816000190483118215151615614df357614df3614c5d565b500290565b8054600080835581156108fc5782815260208120601f830160051c81015b808210156111fa57828255600182019150614e16565b600160401b821115614e4057614e406144e3565b8054828255808310156108fc57600082815260208120601f850160051c8101601f840160051c82019150601f86168015614e8b576000198083018054828460200360031b1c16815550505b505b8181101561376057828155600101614e8d565b8054600082558015614ed5578160005260206000208181015b808210156107e057614eca82614df8565b600182019150614eb9565b5050565b600160401b821115614eed57614eed6144e3565b8054828255808310156108fc576000828152602090208381019082015b808210156111fa57614f1b82614df8565b600182019150614f0a565b8054600080835581156108fc5760016001600160fe1b038311811615614f4e57614f4e614c5d565b60028483526020832084821b81015b80821015614f835784825584848301558483830155846003830155600482019150614f5d565b50505050505050565b600160401b821115614fa057614fa06144e3565b8054828255808310156108fc576001600160fe1b036001818311811615614fc957614fc9614c5d565b6002828611821615614fdd57614fdd614c5d565b60008581526020812090935086821b81019085831b015b80821015610c8d5784825584848301558483830155846003830155600482019150614ff4565b8054600080835581156108fc5760016001600160fe1b03831181161561504257615042614c5d565b60028483526020832084821b81015b80821015614f8357848255615067848301614ea0565b848383015561507860038301614f26565b600482019150615051565b600160401b821115615097576150976144e3565b8054828255808310156108fc576001600160fe1b0360018183118116156150c0576150c0614c5d565b60028286118216156150d4576150d4614c5d565b60008581526020812090935086821b81019085831b015b80821015610c8d57848255615101848301614ea0565b848383015561511260038301614f26565b6004820191506150eb565b600081356106d881614a9f565b6000808335601e1984360301811261514157600080fd5b8301803591506001600160401b0382111561515b57600080fd5b602001915060c08102360382131561447f57600080fd5b61517c8382614f8c565b818160005260208060002060005b86811015614f835783358255828401356001830155604084013560028301556003820160608501356151bb81614a9f565b815460ff191660ff82161782555060808501356151d781614d6d565b6151e08161473f565b815461ff001916600882901b61ff00161782555060a085013561520281614a9f565b815462ff00001916601082901b62ff000016178255505060c093909301926004919091019060010161518a565b813581556020820135600182015560028101604083013561524f81614a9f565b815460ff191660ff821617825550606083013561526b81614a9f565b815461ff001916600882901b61ff0016179050808255608084013561528f81614a9f565b62ff0000601082901b1662ff00001983161791505080825560a08401356152b581614a74565b63ff000000199190911690151560181b63ff000000161790556152db60c0830183614d7a565b6152e88160038501615083565b81600060038501815260208120815b84811015610c8d57607e1986360301843512615311578283fd5b8335860161531f8135614a9f565b825460ff191660ff8235161783556001830161533e6020830183614d7a565b6153488184614ed9565b918652602086209181875b828110156153eb576153658285614d7a565b61536f8188614e2c565b868b5260208b208b8c5b838110156153cf5761538b8535614a9f565b82548260031b60ff811b8060ff893516831b1681198416178655505050602085019450600182019150601f8211156153c7578d91506001830192505b600101615379565b5050505050602082019150600185019450600181019050615353565b50505050506154146153ff6040830161511d565b6002850160ff821660ff198254161781555050565b615421606082018261512a565b9150615431828260038701615172565b505060209390930192600491909101906001016152f7565b81358155600180820160208085013561546181614d6d565b61546a8161473f565b60ff1983541660ff82168117915050808355604086013561548a81614d6d565b6154938161473f565b61ff00600882901b1661ff001983161791505080835560608601356154b781614d6d565b6154c08161473f565b62ff0000601082901b1662ff00001983161791505080835560808601356154e681614d6d565b6154ef8161473f565b63ff000000601882901b1663ff00000019831617845550506002915081840161551b60a0870187614d7a565b600160401b81111561552f5761552f6144e3565b8254818455808210156155ac576001600160fe1b0380821188161561555657615556614c5d565b80831188161561556857615568614c5d565b50600084815285812083881b81019083891b015b808210156155a857828255828a830155828983015561559d6003830161501a565b60048201915061557c565b5050505b508194506155c08360009081526020902090565b925060005b81811015612f7e576155e06155da8785614dc3565b8561522f565b948401946004939093019286016155c5565b8051600a81106144de57600080fd5b80516144de81614d6d565b80516144de81614a9f565b600082601f83011261562857600080fd5b60405160c081018181106001600160401b038211171561564a5761564a6144e3565b6040528060c084018581111561565f57600080fd5b845b8181101561568257805161567481614a9f565b835260209283019201615661565b509195945050505050565b600061018082840312156156a057600080fd5b6156a86144f9565b8251600381106156b757600080fd5b81526156c5602084016155f2565b60208201526156d660408401615601565b60408201526156e76060840161560c565b60608201526156f86080840161560c565b608082015261570a8460a08501615617565b60a0820152610160929092015160c083015250919050565b600181811c9082168061573657607f821691505b6020821081141561575757634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561576f57600080fd5b5051919050565b6000808335601e1984360301811261578d57600080fd5b8301803591506001600160401b038211156157a757600080fd5b602001915060608102360382131561447f57600080fd5b600080835481600182811c9150808316806157da57607f831692505b60208084108214156157fa57634e487b7160e01b86526022600452602486fd5b81801561580e576001811461581f5761584c565b60ff1986168952848901965061584c565b60008a81526020902060005b868110156158445781548b82015290850190830161582b565b505084890196505b509498975050505050505050565b6020808252601390820152724c6567696f6e206973206e6f7420796f75727360681b604082015260600190565b600060ff821660ff84168060ff038211156158a4576158a4614c5d565b019392505050565b60208082526025908201527f4c6567696f6e206e6f74206869676820656e6f756768207175657374696e67206040820152641b195d995b60da1b606082015260800190565b600060ff821660ff81141561590857615908614c5d565b60010192915050565b6000808335601e1984360301811261592857600080fd5b8301803591506001600160401b0382111561594257600080fd5b60200191503681900382131561447f57600080fd5b60006020828403121561596957600080fd5b813561347081614a9f565b600060ff821660ff84168082101561598e5761598e614c5d565b90039392505050565b600082198211156159aa576159aa614c5d565b500190565b81835260006001600160fb1b038311156159c857600080fd5b8260051b8083602087013760009401602001938452509192915050565b6001600160a01b0387811682528616602082015260a060408201819052600090615a1290830186886159af565b8281036060840152615a258185876159af565b8381036080909401939093525050600081526020019695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000808335601e19843603018112615a8457600080fd5b83016020810192503590506001600160401b03811115615aa357600080fd5b8060051b360383131561447f57600080fd5b60018060a01b0384168152826020820152606060408201528135606082015260006020830135601e19843603018112615aed57600080fd5b830180356001600160401b03811115615b0557600080fd5b803603851315615b1457600080fd5b60a06080850152615b2d61010085018260208501615a44565b915050615b3c60408501614aae565b60ff1660a0840152615b516060850185615a6d565b605f19808685030160c0870152615b698483856159af565b9350615b786080880188615a6d565b93509150808685030160e087015250615b928383836159af565b98975050505050505050565b6000825160005b81811015615bbf5760208186018101518583015201615ba5565b81811115615bce576000828501525b509190910192915050565b600082615bf657634e487b7160e01b600052601260045260246000fd5b500690565b600060608083018784526020600a8810615c1757615c17614729565b84810188905260408086018490529186905286916080860160005b88811015615c77578435615c4581614a9f565b60ff90811683528585013590615c5a82614a9f565b168285015284830135838301529385019390850190600101615c32565b509a9950505050505050505050565b600060608284031215615c9857600080fd5b604051606081018181106001600160401b0382111715615cba57615cba6144e3565b6040528251615cc881614a9f565b81526020830151615cd881614a9f565b60208201526040830151615ceb81614a74565b60408201529392505050565b600081518084526020808501945080840160005b83811015615d2757815187529582019590820190600101615d0b565b509495945050505050565b6001600160a01b0385811682528416602082015260a060408201819052600090615d5e90830185615cf7565b8281036060840152615d708185615cf7565b838103608090940193909352505060008152602001949350505050565b6001600160a01b03841681526020808201849052606060408084018290528451848301819052600093608092909183870190888401875b82811015615df95781518051855286810151878601528581015186860152880151888501529286019290850190600101615dc4565b50919b9a5050505050505050505050565b600081615e1957615e19614c5d565b506000190190565b600082821015615e3357615e33614c5d565b500390565b600060ff821660ff84168160ff0481118215151615615e5957615e59614c5d565b029392505050565b60ff8416815260608101615e748461473f565b602082019390935260400152919050565b634e487b7160e01b600052603160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220550dfd52c3222a0f30300048dd867317a70e106b9677fbe49dad7abf9687ccc364736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025e5760003560e01c80638129fc1c11610146578063bedb86fb116100c3578063d3f6760911610087578063d3f6760914610625578063d7dfe4dd14610639578063e520fc7e1461064d578063f10fb58414610661578063f23a6e6114610675578063f2fde38b1461069457600080fd5b8063bedb86fb146105ae578063c43c074c146105c1578063c87d4e07146105eb578063cedec2ff146105fe578063cfe519031461061157600080fd5b80639c54df641161010a5780639c54df6414610542578063a0122ec614610555578063a888306014610569578063abfe37b91461057c578063bc197c811461058f57600080fd5b80638129fc1c146104fa578063821cab0b146105025780638a7bf804146105155780638cdcc4b4146105295780638da5cb5b1461053157600080fd5b80633ea86bfe116101df57806370480275116101a3578063704802751461044b57806370e419451461045e578063715018a614610471578063790f20d9146104795780637ac290a8146104b95780637d7aa1bc146104e757600080fd5b80633ea86bfe1461039e578063452fd6d1146103b65780634bec7954146103c95780635c975abb1461042c578063675857eb1461043757600080fd5b80631b2378c5116102265780631b2378c51461031657806324d7806c146103295780632847a62d14610355578063377e11e0146103785780633c06ef4e1461038b57600080fd5b806301ffc9a7146102635780630a0e28d41461028b57806313bc0b8d146102a0578063150b7a02146102cc5780631785f53c14610303575b600080fd5b610276610271366004614411565b6106a7565b60405190151581526020015b60405180910390f35b61029e610299366004614486565b6106de565b005b610193546102b4906001600160a01b031681565b6040516001600160a01b039091168152602001610282565b6102ea6102da3660046145c8565b630a85bd0160e11b949350505050565b6040516001600160e01b03199091168152602001610282565b61029e61031136600461462f565b6107e6565b61027661032436600461468b565b610831565b61027661033736600461462f565b6001600160a01b031660009081526097602052604090205460ff1690565b6102766103633660046146c0565b600090815261019f6020526040902054151590565b61029e610386366004614486565b610860565b61029e6103993660046146c0565b610901565b6103a861019b5481565b604051908152602001610282565b6103a86103c436600461468b565b610944565b61041b6103d73660046146d9565b805160208183018101805161019c825292820191909301209152805460019091015460ff808216916101008104821691620100008204811691630100000090041685565b60405161028295949392919061474f565b60655460ff16610276565b610194546102b4906001600160a01b031681565b61029e61045936600461462f565b610974565b61029e61046c366004614486565b6109c2565b61029e610abb565b6104a76104873660046146c0565b600090815261019f6020526040902060080154600160a81b900460ff1690565b60405160ff9091168152602001610282565b6104a76104c73660046146c0565b600090815261019f6020526040902060080154600160a01b900460ff1690565b61029e6104f536600461479c565b610af1565b61029e610c97565b61029e610510366004614486565b610d11565b610195546102b4906001600160a01b031681565b610276610e0d565b6033546001600160a01b03166102b4565b61029e610550366004614486565b610edc565b610198546102b4906001600160a01b031681565b61029e610577366004614835565b610f78565b61029e61058a3660046148dd565b61105b565b6102ea61059d3660046149cb565b63bc197c8160e01b95945050505050565b61029e6105bc366004614a82565b611201565b6105d46105cf3660046146c0565b611254565b6040805192835260ff909116602083015201610282565b6103a86105f9366004614ab9565b611433565b61029e61060c366004614b04565b611488565b61019a546102b4906001600160a01b031681565b610199546102b4906001600160a01b031681565b610197546102b4906001600160a01b031681565b610196546102b4906001600160a01b031681565b610192546102b4906001600160a01b031681565b6102ea610683366004614b40565b63f23a6e6160e01b95945050505050565b61029e6106a236600461462f565b611626565b60006001600160e01b03198216630271189760e51b14806106d857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60655460ff161561070a5760405162461bcd60e51b815260040161070190614ba4565b60405180910390fd5b610712610e0d565b61072e5760405162461bcd60e51b815260040161070190614bce565b33321461074d5760405162461bcd60e51b815260040161070190614bfc565b818180806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508251151591506107a290505760405162461bcd60e51b815260040161070190614c22565b60005b828110156107e0576107ce8484838181106107c2576107c2614c47565b905060200201356116be565b806107d881614c73565b9150506107a5565b50505050565b6033546001600160a01b031633146108105760405162461bcd60e51b815260040161070190614c8e565b6001600160a01b03166000908152609760205260409020805460ff19169055565b60008061019c8484604051610847929190614cc3565b9081526040519081900360200190205411905092915050565b6033546001600160a01b0316331461088a5760405162461bcd60e51b815260040161070190614c8e565b60005b818110156108fc576000609760008585858181106108ad576108ad614c47565b90506020020160208101906108c2919061462f565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806108f481614c73565b91505061088d565b505050565b3360009081526097602052604090205460ff16806109225750610922611b14565b61093e5760405162461bcd60e51b815260040161070190614cd3565b61019b55565b600061019c8383604051610959929190614cc3565b90815260405190819003602001902060020154905092915050565b6033546001600160a01b0316331461099e5760405162461bcd60e51b815260040161070190614c8e565b6001600160a01b03166000908152609760205260409020805460ff19166001179055565b60655460ff16156109e55760405162461bcd60e51b815260040161070190614ba4565b6109ed610e0d565b610a095760405162461bcd60e51b815260040161070190614bce565b333214610a285760405162461bcd60e51b815260040161070190614bfc565b81818080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050825115159150610a7d90505760405162461bcd60e51b815260040161070190614c22565b60005b828110156107e057610aa9848483818110610a9d57610a9d614c47565b90506020020135611b38565b80610ab381614c73565b915050610a80565b6033546001600160a01b03163314610ae55760405162461bcd60e51b815260040161070190614c8e565b610aef6000611cd0565b565b3360009081526097602052604090205460ff1680610b125750610b12611b14565b610b2e5760405162461bcd60e51b815260040161070190614cd3565b610b388686610831565b610b765760405162461bcd60e51b815260206004820152600f60248201526e169bdb99481a5cc81a5b9d985b1a59608a1b6044820152606401610701565b600061019c8787604051610b8b929190614cc3565b908152604051908190036020019020600281015490915084148015610baf57508382145b610bef5760405162461bcd60e51b8152602060048201526011602482015270426164206172726179206c656e6774687360781b6044820152606401610701565b60005b84811015610c8d57858582818110610c0c57610c0c614c47565b90506020020135826002018281548110610c2857610c28614c47565b6000918252602090912060049091020155838382818110610c4b57610c4b614c47565b90506020020135826002018281548110610c6757610c67614c47565b600091825260209091206001600490920201015580610c8581614c73565b915050610bf2565b5050505050505050565b600054610100900460ff16610cb25760005460ff1615610cb6565b303b155b610cd25760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015610cf4576000805461ffff19166101011790555b610cfc611d22565b8015610d0e576000805461ff00191690555b50565b60655460ff1615610d345760405162461bcd60e51b815260040161070190614ba4565b610d3c610e0d565b610d585760405162461bcd60e51b815260040161070190614bce565b333214610d775760405162461bcd60e51b815260040161070190614bfc565b80610dc45760405162461bcd60e51b815260206004820152601b60248201527f4e6f20737461727420717565737420706172616d7320676976656e00000000006044820152606401610701565b60005b818110156108fc57610dfb838383818110610de457610de4614c47565b9050602002810190610df69190614d4d565b611d87565b80610e0581614c73565b915050610dc7565b610192546000906001600160a01b031615801590610e365750610193546001600160a01b031615155b8015610e4d5750610194546001600160a01b031615155b8015610e645750610195546001600160a01b031615155b8015610e7b5750610196546001600160a01b031615155b8015610e925750610197546001600160a01b031615155b8015610ea95750610198546001600160a01b031615155b8015610ec05750610199546001600160a01b031615155b8015610ed7575061019a546001600160a01b031615155b905090565b6033546001600160a01b03163314610f065760405162461bcd60e51b815260040161070190614c8e565b60005b818110156108fc57600160976000858585818110610f2957610f29614c47565b9050602002016020810190610f3e919061462f565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610f7081614c73565b915050610f09565b3360009081526097602052604090205460ff1680610f995750610f99611b14565b610fb55760405162461bcd60e51b815260040161070190614cd3565b61019280546001600160a01b03199081166001600160a01b039b8c161790915561019380548216998b169990991790985561019480548916978a16979097179096556101958054881695891695909517909455610196805487169388169390931790925561019780548616918716919091179055610198805485169186169190911790556101998054841691851691909117905561019a80549092169216919091179055565b3360009081526097602052604090205460ff168061107c575061107c611b14565b6110985760405162461bcd60e51b815260040161070190614cd3565b6110e583838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506127bb915050565b156111325760405162461bcd60e51b815260206004820152601960248201527f5a6f6e65206e616d652063616e6e6f7420626520626c616e6b000000000000006044820152606401610701565b61113c8383610831565b1561117f5760405162461bcd60e51b81526020600482015260136024820152725a6f6e6520616c72656164792065786973747360681b6044820152606401610701565b80356111cd5760405162461bcd60e51b815260206004820152601b60248201527f5a6f6e65206d757374206861766520612073746172742074696d6500000000006044820152606401610701565b8061019c84846040516111e1929190614cc3565b9081526040519081900360200190206111fa8282615449565b5050505050565b3360009081526097602052604090205460ff16806112225750611222611b14565b61123e5760405162461bcd60e51b815260040161070190614cd3565b801561124c57610d0e612814565b610d0e612889565b610195546040516378afdef960e11b815260048101839052600091829182916001600160a01b03169063f15fbdf2906024016101806040518083038186803b15801561129f57600080fd5b505afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d7919061568d565b9050600061138461019f6000878152602001908152602001600020600701805461130090615722565b80601f016020809104026020016040519081016040528092919081815260200182805461132c90615722565b80156113795780601f1061134e57610100808354040283529160200191611379565b820191906000526020600020905b81548152906001019060200180831161135c57829003601f168201915b505050505083612903565b61019254600087815261019f6020526040808220600101549051634ad30a7560e01b81526004810191909152929350916001600160a01b0390911690634ad30a759060240160206040518083038186803b1580156113e157600080fd5b505afa1580156113f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611419919061575d565b9050611427868484846129de565b94509450505050915091565b600061019c8484604051611448929190614cc3565b90815260200160405180910390206002018260ff168154811061146d5761146d614c47565b90600052602060002090600402016000015490509392505050565b60655460ff16156114ab5760405162461bcd60e51b815260040161070190614ba4565b6114b3610e0d565b6114cf5760405162461bcd60e51b815260040161070190614bce565b3332146114ee5760405162461bcd60e51b815260040161070190614bfc565b8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505082511515915061154390505760405162461bcd60e51b815260040161070190614c22565b858414801561155157508582145b61159d5760405162461bcd60e51b815260206004820152601a60248201527f426164206172726179206c656e6774687320666f7220706c61790000000000006044820152606401610701565b60005b86811015610c8d576116148888838181106115bd576115bd614c47565b905060200201358787848181106115d6576115d6614c47565b90506020028101906115e89190615776565b8787868181106115fa576115fa614c47565b905060200201602081019061160f9190614a82565b612cb5565b8061161e81614c73565b9150506115a0565b6033546001600160a01b031633146116505760405162461bcd60e51b815260040161070190614c8e565b6001600160a01b0381166116b55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610701565b610d0e81611cd0565b600081815261019f60205260408082206101955491516378afdef960e11b8152600481018590529092916001600160a01b03169063f15fbdf2906024016101806040518083038186803b15801561171457600080fd5b505afa158015611728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174c919061568d565b9050600061019c8360070160405161176491906157be565b90815260405190819003602001902060088401549091506001600160a01b031633146117a25760405162461bcd60e51b81526004016107019061585a565b61019254600085815261019f6020526040808220600101549051634ad30a7560e01b815291926001600160a01b031691634ad30a75916117e89160040190815260200190565b60206040518083038186803b15801561180057600080fd5b505afa158015611814573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611838919061575d565b905061184985858585856001612f89565b6002820154600885015461186890600160a01b900460ff166001615887565b60ff1611156118b05760405162461bcd60e51b8152602060048201526014602482015273105b1c9958591e48185d081b185cdd081c185c9d60621b6044820152606401610701565b60088401546002830180549091600160a01b900460ff169081106118d6576118d6614c47565b6000918252602090912060026004909202010154606084015160ff6101009092048216911610156119195760405162461bcd60e51b8152600401610701906158ac565b60088401546002830180549091600160a01b900460ff1690811061193f5761193f614c47565b906000526020600020906004020160020160039054906101000a900460ff161580611975575060006119738560040161316b565b115b6119c15760405162461bcd60e51b815260206004820152601d60248201527f4e6f207472656173757265207374616b656420666f72206c6567696f6e0000006044820152606401610701565b610192546040805163433c53d960e11b815290516000926001600160a01b031691638678a7b291600480830192602092919082900301818787803b158015611a0857600080fd5b505af1158015611a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a40919061575d565b42865560088601805460ff60a81b198116600160a01b9182900460ff908116600160a81b02919091178084559394509204909116906014611a80836158f1565b82546101009290920a60ff8181021990931691831602179091556000600288015560038701805461ffff1916905560018701839055600887015460408051338152602081018b9052908101859052600160a01b90910490911660608201527f6637022d9de6a2060f00e17833969643de3940f9fc4ea37f4e755ae5121b13c3915060800160405180910390a1505050505050565b600033611b296033546001600160a01b031690565b6001600160a01b031614905090565b600081815261019f60205260408082206101955491516378afdef960e11b8152600481018590529092916001600160a01b03169063f15fbdf2906024016101806040518083038186803b158015611b8e57600080fd5b505afa158015611ba2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc6919061568d565b9050600061019c83600701604051611bde91906157be565b90815260405190819003602001902060088401549091506001600160a01b03163314611c1c5760405162461bcd60e51b81526004016107019061585a565b61019254600085815261019f6020526040808220600101549051634ad30a7560e01b815291926001600160a01b031691634ad30a7591611c629160040190815260200190565b60206040518083038186803b158015611c7a57600080fd5b505afa158015611c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb2919061575d565b9050611cc385858585856001612f89565b6111fa8585858585613175565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611d3d5760005460ff1615611d41565b303b155b611d5d5760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015611d7f576000805461ffff19166101011790555b610cfc6133f7565b8035600081815261019f602052604090205415611de65760405162461bcd60e51b815260206004820152601a60248201527f4c6567696f6e20697320616c7265616479207175657374696e670000000000006044820152606401610701565b611df66103246020840184615911565b611e315760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207a6f6e6560a01b6044820152606401610701565b6000611e436103c46020850185615911565b90506000611e576060850160408601615957565b60ff16118015611e79575080611e736060850160408601615957565b60ff1611155b611ec55760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420616476616e636520746f20706172740000000000000000006044820152606401610701565b610195546040516378afdef960e11b8152600481018490526000916001600160a01b03169063f15fbdf2906024016101806040518083038186803b158015611f0c57600080fd5b505afa158015611f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f44919061568d565b9050600281516002811115611f5b57611f5b614729565b1415611fa95760405162461bcd60e51b815260206004820152601d60248201527f526563727569742063616e6e6f7420616476616e6365642071756573740000006044820152606401610701565b6000805b611fbd6060870160408801615957565b60ff1681101561216e57600061019c611fd96020890189615911565b604051611fe7929190614cc3565b9081526020016040518091039020600201828154811061200957612009614c47565b6000918252602090912060026004909202010154606085015160ff610100909204821692501681111561204e5760405162461bcd60e51b8152600401610701906158ac565b600061019c61206060208a018a615911565b60405161206e929190614cc3565b9081526020016040518091039020600201838154811061209057612090614c47565b906000526020600020906004020160020160039054906101000a900460ff16905083806120ba5750805b935060016120ce60608a0160408b01615957565b6120d89190615974565b60ff16831080156120e65750805b156121595760405162461bcd60e51b815260206004820152603860248201527f43616e6e6f7420616476616e636564207061737420612070617274207468617460448201527f20726571756972657320747265617375726520747269616400000000000000006064820152608401610701565b5050808061216690614c73565b915050611fad565b5061217c6080860186614d7a565b905061218b6060870187614d7a565b9050146121d15760405162461bcd60e51b8152602060048201526014602482015273426164207472656173757265206c656e6774687360601b6044820152606401610701565b8015806121ec575060006121e86060870187614d7a565b9050115b6122445760405162461bcd60e51b8152602060048201526024808201527f4e65656420747265617375726520746f20706c617920747265617375726520746044820152631c9a585960e21b6064820152608401610701565b6000806122936122576020890189615911565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250612903915050565b905060005b6122a56060890189614d7a565b90508110156123f85760006122bd60608a018a614d7a565b838181106122cd576122cd614c47565b90506020020135118015612304575060006122eb60808a018a614d7a565b838181106122fb576122fb614c47565b90506020020135115b6123505760405162461bcd60e51b815260206004820152601960248201527f426164207472656173757265206964206f7220616d6f756e74000000000000006044820152606401610701565b61235d6080890189614d7a565b8281811061236d5761236d614c47565b905060200201358361237f9190615997565b92508160ff168311156123e65760405162461bcd60e51b815260206004820152602960248201527f546f6f206d616e792074726561737572657320666f7220636f6e7374656c6c6160448201526874696f6e2072616e6b60b81b6064820152608401610701565b806123f081614c73565b915050612298565b50610192546040805163433c53d960e11b815290516000926001600160a01b031691638678a7b291600480830192602092919082900301818787803b15801561244057600080fd5b505af1158015612454573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612478919061575d565b600088815261019f602090815260409091204281556001018290559091506124a290890189615911565b600089815261019f602052604090206124c092600790910191614378565b50600087815261019f60205260409081902060080180546001600160a01b031916331790556124f59060608a01908a01615957565b600088815261019f6020526040812060088101805461ffff60a01b1916600160a01b60ff959095169490940260ff60a81b191693909317909255600282018190556003909101805461ffff191690555b61255260608a018a614d7a565b905081101561266f57600061256a60608b018b614d7a565b8381811061257a5761257a614c47565b9050602002013590506125ac8161019f60008c815260200190815260200160002060040161345c90919063ffffffff16565b156125f95760405162461bcd60e51b815260206004820152601e60248201527f4475706c696361746520747265617375726520696420696e20617272617900006044820152606401610701565b600089815261019f602052604090206126159060040182613477565b5061262360808b018b614d7a565b8381811061263357612633614c47565b60008c815261019f602090815260408083209683526006909601815294902093029190910135909155508061266781614c73565b915050612545565b50610194546040516383291f8760e01b8152336004820152306024820152604481018990526001600160a01b03909116906383291f8790606401600060405180830381600087803b1580156126c357600080fd5b505af11580156126d7573d6000803e3d6000fd5b50600092506126ec91505060608a018a614d7a565b9050111561277657610196546001600160a01b0316632eb2c2d6333061271560608d018d614d7a565b61272260808f018f614d7a565b6040518763ffffffff1660e01b8152600401612743969594939291906159e5565b600060405180830381600087803b15801561275d57600080fd5b505af1158015612771573d6000803e3d6000fd5b505050505b7f6c0d8f3939be2a5b9dcf5ce392c338774f1e1fce2cfa6a61a9ad81ad1dd3dd1933828a6040516127a993929190615ab5565b60405180910390a15050505050505050565b6000816040516020016127ce9190615b9e565b60405160208183030381529060405280519060200120836040516020016127f59190615b9e565b6040516020818303038152906040528051906020012014905092915050565b60655460ff16156128375760405162461bcd60e51b815260040161070190614ba4565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861286c3390565b6040516001600160a01b03909116815260200160405180910390a1565b60655460ff166128d25760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610701565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361286c565b6000808260a0015161019c8560405161291c9190615b9e565b9081526040519081900360200190206001015460ff6201000090910416600581111561294a5761294a614729565b6006811061295a5761295a614c47565b6020020151905060008360a0015161019c866040516129799190615b9e565b9081526040519081900360200190206001015460ff63010000009091041660058111156129a8576129a8614729565b600681106129b8576129b8614c47565b602002015190508060ff168260ff1611156129d5575090506106d8565b91506106d89050565b600084815261019f60205260408120548190612a355760405162461bcd60e51b81526020600482015260166024820152754c6567696f6e206973206e6f74207175657374696e6760501b6044820152606401610701565b600086815261019f6020526040808220905190919061019c90612a5c9060078501906157be565b90815260405190819003602001902060028084015460038501546008860154939450909260ff91821692850191612a9e91600191600160a01b90910416615974565b60ff1681548110612ab157612ab1614c47565b906000526020600020906004020160020160039054906101000a900460ff168015612adc5750600082115b8015612ae85750600081115b15612b125761019b54612afb9082614dd9565b612b059083615997565b95509350612cac92505050565b60ff808916600090815261019e602052604081205460088701549192908116918391600160a81b909104165b6008880154600160a01b900460ff16811015612c8557866002018181548110612b6957612b69614c47565b90600052602060002090600402016000015484612b869190615997565b935061019d60008e600001516002811115612ba357612ba3614729565b6002811115612bb457612bb4614729565b815260208101919091526040016000205460ff1615612c73576000876002018281548110612be457612be4614c47565b600091825260209091206002600490920201015460ff90811691508416811115612c7157612c128482615974565b60ff16612c216101008e615bd9565b1015612c695782612c31816158f1565b935050876002018281548110612c4957612c49614c47565b90600052602060002090600402016001015485612c669190615997565b94505b60088c901c9b505b505b80612c7d81614c73565b915050612b3e565b5060008d815261019f6020526040902054612ca1908490615997565b985096505050505050505b94509492505050565b600084815261019f60205260408082206101955491516378afdef960e11b8152600481018890529092916001600160a01b03169063f15fbdf2906024016101806040518083038186803b158015612d0b57600080fd5b505afa158015612d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d43919061568d565b9050600061019c83600701604051612d5b91906157be565b90815260405190819003602001902060088401549091506001600160a01b03163314612d995760405162461bcd60e51b81526004016107019061585a565b61019254600088815261019f6020526040808220600101549051634ad30a7560e01b815291926001600160a01b031691634ad30a7591612ddf9160040190815260200190565b60206040518083038186803b158015612df757600080fd5b505afa158015612e0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2f919061575d565b9050612e4088858585856000612f89565b612e4b878786613483565b6101995460208401516040516330019d4b60e01b81526000926001600160a01b0316916330019d4b91612e869186918d908d90600401615bfb565b60606040518083038186803b158015612e9e57600080fd5b505afa158015612eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed69190615c86565b426002870155602081810151600388018054845160ff93841661ffff199092168217610100949091169384021790915560408085015181513381529485018f9052151590840152606083019190915260808201529091507f9cc74f6243b89778b7e86d5b933c4146bd93203932a12bfe7ad7625d433e67ae9060a00160405180910390a1858015612f6c5750602081015160ff16155b15612f7e57612f7e8986868686613175565b505050505050505050565b6000613021866007018054612f9d90615722565b80601f0160208091040260200160405190810160405280929190818152602001828054612fc990615722565b80156130165780601f10612feb57610100808354040283529160200191613016565b820191906000526020600020905b815481529060010190602001808311612ff957829003601f168201915b505050505086612903565b90506000613031888784876129de565b5090508042101561309e5760405162461bcd60e51b815260206004820152603160248201527f4c6567696f6e20686173206e6f742066696e69736865642074686973207061726044820152701d081bd9881d1a19481e9bdb99481e595d607a1b6064820152608401610701565b8280156130f95750600887015460028601906130c690600190600160a01b900460ff16615974565b60ff16815481106130d9576130d9614c47565b906000526020600020906004020160020160039054906101000a900460ff165b801561310757506002870154155b15610c8d5760405162461bcd60e51b815260206004820152602e60248201527f486173206e6f7420706c6179656420747265617375726520747269616420666f60448201526d1c8818dd5c9c995b9d081c185c9d60921b6064820152608401610701565b60006106d8825490565b610193546060840151604051632fb44d2760e11b81526004810188905260ff90911660248201526001600160a01b0390911690635f689a4e90604401600060405180830381600087803b1580156131cb57600080fd5b505af11580156131df573d6000803e3d6000fd5b5050505060006131f185858585613768565b60008655610194546040516383291f8760e01b8152306004820152336024820152604481018990529192506001600160a01b0316906383291f8790606401600060405180830381600087803b15801561324957600080fd5b505af115801561325d573d6000803e3d6000fd5b50505050600061326f86600401613cce565b9050600081516001600160401b0381111561328c5761328c6144e3565b6040519080825280602002602001820160405280156132b5578160200160208202803683370190505b50905060005b8251811015613352576132f38382815181106132d9576132d9614c47565b602002602001015189600401613cdb90919063ffffffff16565b5087600601600084838151811061330c5761330c614c47565b602002602001015181526020019081526020016000205482828151811061333557613335614c47565b60209081029190910101528061334a81614c73565b9150506132bb565b508151156133c45761019654604051631759616b60e11b81526001600160a01b0390911690632eb2c2d690613391903090339087908790600401615d32565b600060405180830381600087803b1580156133ab57600080fd5b505af11580156133bf573d6000803e3d6000fd5b505050505b7f9949f99e59b9a76e12491767b7369cea6085b2e0f953d867d6a20484c12b105c3389856040516127a993929190615d8d565b600054610100900460ff166134125760005460ff1615613416565b303b155b6134325760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015613454576000805461ffff19166101011790555b610cfc613ce7565b600081815260018301602052604081205415155b9392505050565b60006134708383613f02565b81158015906134925750600482105b6134e95760405162461bcd60e51b815260206004820152602260248201527f426164206e756d626572206f66207472656173757265207472696164206d6f76604482015261657360f01b6064820152608401610701565b6000826001600160401b03811115613503576135036144e3565b60405190808252806020026020018201604052801561354857816020015b60408051808201909152600080825260208201528152602001906001900390816135215790505b5090506000805b8481101561376057600086868381811061356b5761356b614c47565b90506060020160400135905061358d818660040161345c90919063ffffffff16565b6135ea5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420706c6179207472656173757265207468617420776173206e6f6044820152671d081cdd185ad95960c21b6064820152608401610701565b6000805b85518110156136e3578286828151811061360a5761360a614c47565b60200260200101516000015114156136d1576001915085818151811061363257613632614c47565b6020026020010151602001516000141561369e5760405162461bcd60e51b815260206004820152602760248201527f55736564206d6f7265207472656173757265207468616e207768617420776173604482015266081cdd185ad95960ca1b6064820152608401610701565b8581815181106136b0576136b0614c47565b602002602001015160200180518091906136c990615e0a565b9052506136e3565b806136db81614c73565b9150506135ee565b508061374b57604051806040016040528083815260200160018860060160008681526020019081526020016000205461371c9190615e21565b81525085858151811061373157613731614c47565b6020026020010181905250838061374790614c73565b9450505b5050808061375890614c73565b91505061354f565b505050505050565b606060008360020160018760080160149054906101000a900460ff1661378e9190615974565b60ff16815481106137a1576137a1614c47565b90600052602060002090600402019050827f270403fba6eda13e1a219e01f1fb9cac4267cb529255cf0cb111921f931242186040516020016137ed929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c925060008560000151600281111561382057613820614729565b905060008660400151600581111561383a5761383a614729565b60038401549091506000906001600160401b0381111561385c5761385c6144e3565b6040519080825280602002602001820160405280156138b857816020015b6138a56040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020019060019003908161387a5790505b50905060005b6003850154811015613cc15760008560030182815481106138e1576138e1614c47565b60009182526020822060038e015460049290920201600281015490935061391391610100900460ff9081169116615e38565b82600101878154811061392857613928614c47565b90600052602060002001868154811061394357613943614c47565b600091825260209182902091810490910154845461397192601f166101000a90910460ff9081169116615887565b61397b9190615887565b60ff169050600060ff8210613992575060016139b7565b81156139b757816139a56101008c615bd9565b10156139af575060015b60088a901c99505b8015613cab5760006139c98b85613f51565b8054909150158015906139e0575060008160010154115b15613aa45780600001548686815181106139fc576139fc614c47565b602002602001015160000181815250508060010154868681518110613a2357613a23614c47565b60209081029190910181015101526101975481546001830154604051630ab714fb60e11b8152336004820152602481019290925260448201526001600160a01b039091169063156e29f690606401600060405180830381600087803b158015613a8b57600080fd5b505af1158015613a9f573d6000803e3d6000fd5b505050505b600281015415613b49578060020154868681518110613ac557613ac5614c47565b602090810291909101015160409081019190915261019a5460028301549151630ab714fb60e11b81523360048201526024810192909252600160448301526001600160a01b03169063156e29f690606401600060405180830381600087803b158015613b3057600080fd5b505af1158015613b44573d6000803e3d6000fd5b505050505b600381015460ff1615613ca257600061019860009054906101000a90046001600160a01b03166001600160a01b031663580364e08360030160009054906101000a900460ff168460030160019054906101000a900460ff168f6040518463ffffffff1660e01b8152600401613bc093929190615e61565b60206040518083038186803b158015613bd857600080fd5b505afa158015613bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c10919061575d565b905080878781518110613c2557613c25614c47565b60209081029190910101516060015261019654604051630ab714fb60e11b815233600482015260248101839052600160448201526001600160a01b039091169063156e29f690606401600060405180830381600087803b158015613c8857600080fd5b505af1158015613c9c573d6000803e3d6000fd5b50505050505b60088b901c9a50505b5050508080613cb990614c73565b9150506138be565b5098975050505050505050565b6060600061347083614067565b600061347083836140c3565b600054610100900460ff16613d025760005460ff1615613d06565b303b155b613d225760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015613d44576000805461ffff19166101011790555b613d4c6141b6565b613d5461421b565b613d5c61421b565b6201518061019b557f13dcb3c6205eccc5df5a4a7821d488c75d9d361908855b59d022fe13c7bb4f1d805460ff199081169091557f228719b3ab53201bbb41968c40b0b5cdf287f8c98ba3ec9532f722219a6d86ff80548216600117905561019e6020527f2d695d1bdc89be0990c9b1cefd0e589f7fbb3368bfb8d91126956a95dcf1607380548216600a1790557f1482f8fde77c2e0a1223b839dd85e5e0d40575a23bb6b13896f241a0b36fe0d880548216600f1790557f819c8b3e70c1a841f15170a81b2fad3b9dd6363490e4d79d5e443edaf01bbd658054821660141790557ff166615731f9a0da5f995c890da9823aee980021e1f67a3a50824b9391ea855f8054821660171790557f5fc73781db4fef9135a7751bb16b9dc0cf5d8f49924b6290e697d3ce5362e55b8054821660261790557f0c0534c4fd269d874c4e3ccf61cdfc386596ea47184f1d857725cfeaab13fd5080548216603317905560076000527f52fc7babecae6ce4e4dc8870a20313c060d91987e43bc7d10bf81d0e02b5bebc8054604092169190911790558015610d0e576000805461ff001916905550565b6000818152600183016020526040812054613f49575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106d8565b5060006106d8565b600381015460009060011415613f8c5781600301600081548110613f7757613f77614c47565b906000526020600020906004020190506106d8565b6000613f9a61010085615bd9565b90506000600885901c945060005b600385015481101561401e576000856003018281548110613fcb57613fcb614c47565b600091825260209091206004909102016003810154909150613ff69062010000900460ff1684615997565b92508284101561400b5793506106d892505050565b508061401681614c73565b915050613fa8565b5060405162461bcd60e51b815260206004820152601860248201527f426164206f64647320666f72207a6f6e652072657761726400000000000000006044820152606401610701565b6060816000018054806020026020016040519081016040528092919081815260200182805480156140b757602002820191906000526020600020905b8154815260200190600101908083116140a3575b50505050509050919050565b600081815260018301602052604081205480156141ac5760006140e7600183615e21565b85549091506000906140fb90600190615e21565b905081811461416057600086600001828154811061411b5761411b614c47565b906000526020600020015490508087600001848154811061413e5761413e614c47565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061417157614171615e85565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106d8565b60009150506106d8565b600054610100900460ff166141d15760005460ff16156141d5565b303b155b6141f15760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff16158015614213576000805461ffff19166101011790555b610cfc614242565b600054610100900460ff16610aef5760405162461bcd60e51b815260040161070190615e9b565b600054610100900460ff1661425d5760005460ff1615614261565b303b155b61427d5760405162461bcd60e51b815260040161070190614cff565b600054610100900460ff1615801561429f576000805461ffff19166101011790555b6142a76142b7565b6142af6142e6565b610cfc612814565b600054610100900460ff166142de5760405162461bcd60e51b815260040161070190615e9b565b610aef614315565b600054610100900460ff1661430d5760405162461bcd60e51b815260040161070190615e9b565b610aef614345565b600054610100900460ff1661433c5760405162461bcd60e51b815260040161070190615e9b565b610aef33611cd0565b600054610100900460ff1661436c5760405162461bcd60e51b815260040161070190615e9b565b6065805460ff19169055565b82805461438490615722565b90600052602060002090601f0160209004810192826143a657600085556143ec565b82601f106143bf5782800160ff198235161785556143ec565b828001600101855582156143ec579182015b828111156143ec5782358255916020019190600101906143d1565b506143f89291506143fc565b5090565b5b808211156143f857600081556001016143fd565b60006020828403121561442357600080fd5b81356001600160e01b03198116811461347057600080fd5b60008083601f84011261444d57600080fd5b5081356001600160401b0381111561446457600080fd5b6020830191508360208260051b850101111561447f57600080fd5b9250929050565b6000806020838503121561449957600080fd5b82356001600160401b038111156144af57600080fd5b6144bb8582860161443b565b90969095509350505050565b80356001600160a01b03811681146144de57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561451b5761451b6144e3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614549576145496144e3565b604052919050565b60006001600160401b0383111561456a5761456a6144e3565b61457d601f8401601f1916602001614521565b905082815283838301111561459157600080fd5b828260208301376000602084830101529392505050565b600082601f8301126145b957600080fd5b61347083833560208501614551565b600080600080608085870312156145de57600080fd5b6145e7856144c7565b93506145f5602086016144c7565b92506040850135915060608501356001600160401b0381111561461757600080fd5b614623878288016145a8565b91505092959194509250565b60006020828403121561464157600080fd5b613470826144c7565b60008083601f84011261465c57600080fd5b5081356001600160401b0381111561467357600080fd5b60208301915083602082850101111561447f57600080fd5b6000806020838503121561469e57600080fd5b82356001600160401b038111156146b457600080fd5b6144bb8582860161464a565b6000602082840312156146d257600080fd5b5035919050565b6000602082840312156146eb57600080fd5b81356001600160401b0381111561470157600080fd5b8201601f8101841361471257600080fd5b61472184823560208401614551565b949350505050565b634e487b7160e01b600052602160045260246000fd5b60068110610d0e57610d0e614729565b85815260a0810161475f8661473f565b85602083015261476e8561473f565b84604083015261477d8461473f565b83606083015261478c8361473f565b8260808301529695505050505050565b600080600080600080606087890312156147b557600080fd5b86356001600160401b03808211156147cc57600080fd5b6147d88a838b0161464a565b909850965060208901359150808211156147f157600080fd5b6147fd8a838b0161443b565b9096509450604089013591508082111561481657600080fd5b5061482389828a0161443b565b979a9699509497509295939492505050565b60008060008060008060008060006101208a8c03121561485457600080fd5b61485d8a6144c7565b985061486b60208b016144c7565b975061487960408b016144c7565b965061488760608b016144c7565b955061489560808b016144c7565b94506148a360a08b016144c7565b93506148b160c08b016144c7565b92506148bf60e08b016144c7565b91506148ce6101008b016144c7565b90509295985092959850929598565b6000806000604084860312156148f257600080fd5b83356001600160401b038082111561490957600080fd5b6149158783880161464a565b9095509350602086013591508082111561492e57600080fd5b50840160c0818703121561494157600080fd5b809150509250925092565b600082601f83011261495d57600080fd5b813560206001600160401b03821115614978576149786144e3565b8160051b614987828201614521565b92835284810182019282810190878511156149a157600080fd5b83870192505b848310156149c0578235825291830191908301906149a7565b979650505050505050565b600080600080600060a086880312156149e357600080fd5b6149ec866144c7565b94506149fa602087016144c7565b935060408601356001600160401b0380821115614a1657600080fd5b614a2289838a0161494c565b94506060880135915080821115614a3857600080fd5b614a4489838a0161494c565b93506080880135915080821115614a5a57600080fd5b50614a67888289016145a8565b9150509295509295909350565b8015158114610d0e57600080fd5b600060208284031215614a9457600080fd5b813561347081614a74565b60ff81168114610d0e57600080fd5b80356144de81614a9f565b600080600060408486031215614ace57600080fd5b83356001600160401b03811115614ae457600080fd5b614af08682870161464a565b909450925050602084013561494181614a9f565b60008060008060008060608789031215614b1d57600080fd5b86356001600160401b0380821115614b3457600080fd5b6147d88a838b0161443b565b600080600080600060a08688031215614b5857600080fd5b614b61866144c7565b9450614b6f602087016144c7565b9350604086013592506060860135915060808601356001600160401b03811115614b9857600080fd5b614a67888289016145a8565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60208082526014908201527310dbdb9d1c9858dd1cc8185c995b89dd081cd95d60621b604082015260600190565b6020808252600c908201526b4e6f20636f6e74726163747360a01b604082015260600190565b6020808252600b908201526a456d70747920617272617960a81b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614c8757614c87614c5d565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b8183823760009101908152919050565b6020808252601290820152712737ba1030b236b4b71037b91037bbb732b960711b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60008235609e19833603018112614d6357600080fd5b9190910192915050565b60068110610d0e57600080fd5b6000808335601e19843603018112614d9157600080fd5b8301803591506001600160401b03821115614dab57600080fd5b6020019150600581901b360382131561447f57600080fd5b6000823560de19833603018112614d6357600080fd5b6000816000190483118215151615614df357614df3614c5d565b500290565b8054600080835581156108fc5782815260208120601f830160051c81015b808210156111fa57828255600182019150614e16565b600160401b821115614e4057614e406144e3565b8054828255808310156108fc57600082815260208120601f850160051c8101601f840160051c82019150601f86168015614e8b576000198083018054828460200360031b1c16815550505b505b8181101561376057828155600101614e8d565b8054600082558015614ed5578160005260206000208181015b808210156107e057614eca82614df8565b600182019150614eb9565b5050565b600160401b821115614eed57614eed6144e3565b8054828255808310156108fc576000828152602090208381019082015b808210156111fa57614f1b82614df8565b600182019150614f0a565b8054600080835581156108fc5760016001600160fe1b038311811615614f4e57614f4e614c5d565b60028483526020832084821b81015b80821015614f835784825584848301558483830155846003830155600482019150614f5d565b50505050505050565b600160401b821115614fa057614fa06144e3565b8054828255808310156108fc576001600160fe1b036001818311811615614fc957614fc9614c5d565b6002828611821615614fdd57614fdd614c5d565b60008581526020812090935086821b81019085831b015b80821015610c8d5784825584848301558483830155846003830155600482019150614ff4565b8054600080835581156108fc5760016001600160fe1b03831181161561504257615042614c5d565b60028483526020832084821b81015b80821015614f8357848255615067848301614ea0565b848383015561507860038301614f26565b600482019150615051565b600160401b821115615097576150976144e3565b8054828255808310156108fc576001600160fe1b0360018183118116156150c0576150c0614c5d565b60028286118216156150d4576150d4614c5d565b60008581526020812090935086821b81019085831b015b80821015610c8d57848255615101848301614ea0565b848383015561511260038301614f26565b6004820191506150eb565b600081356106d881614a9f565b6000808335601e1984360301811261514157600080fd5b8301803591506001600160401b0382111561515b57600080fd5b602001915060c08102360382131561447f57600080fd5b61517c8382614f8c565b818160005260208060002060005b86811015614f835783358255828401356001830155604084013560028301556003820160608501356151bb81614a9f565b815460ff191660ff82161782555060808501356151d781614d6d565b6151e08161473f565b815461ff001916600882901b61ff00161782555060a085013561520281614a9f565b815462ff00001916601082901b62ff000016178255505060c093909301926004919091019060010161518a565b813581556020820135600182015560028101604083013561524f81614a9f565b815460ff191660ff821617825550606083013561526b81614a9f565b815461ff001916600882901b61ff0016179050808255608084013561528f81614a9f565b62ff0000601082901b1662ff00001983161791505080825560a08401356152b581614a74565b63ff000000199190911690151560181b63ff000000161790556152db60c0830183614d7a565b6152e88160038501615083565b81600060038501815260208120815b84811015610c8d57607e1986360301843512615311578283fd5b8335860161531f8135614a9f565b825460ff191660ff8235161783556001830161533e6020830183614d7a565b6153488184614ed9565b918652602086209181875b828110156153eb576153658285614d7a565b61536f8188614e2c565b868b5260208b208b8c5b838110156153cf5761538b8535614a9f565b82548260031b60ff811b8060ff893516831b1681198416178655505050602085019450600182019150601f8211156153c7578d91506001830192505b600101615379565b5050505050602082019150600185019450600181019050615353565b50505050506154146153ff6040830161511d565b6002850160ff821660ff198254161781555050565b615421606082018261512a565b9150615431828260038701615172565b505060209390930192600491909101906001016152f7565b81358155600180820160208085013561546181614d6d565b61546a8161473f565b60ff1983541660ff82168117915050808355604086013561548a81614d6d565b6154938161473f565b61ff00600882901b1661ff001983161791505080835560608601356154b781614d6d565b6154c08161473f565b62ff0000601082901b1662ff00001983161791505080835560808601356154e681614d6d565b6154ef8161473f565b63ff000000601882901b1663ff00000019831617845550506002915081840161551b60a0870187614d7a565b600160401b81111561552f5761552f6144e3565b8254818455808210156155ac576001600160fe1b0380821188161561555657615556614c5d565b80831188161561556857615568614c5d565b50600084815285812083881b81019083891b015b808210156155a857828255828a830155828983015561559d6003830161501a565b60048201915061557c565b5050505b508194506155c08360009081526020902090565b925060005b81811015612f7e576155e06155da8785614dc3565b8561522f565b948401946004939093019286016155c5565b8051600a81106144de57600080fd5b80516144de81614d6d565b80516144de81614a9f565b600082601f83011261562857600080fd5b60405160c081018181106001600160401b038211171561564a5761564a6144e3565b6040528060c084018581111561565f57600080fd5b845b8181101561568257805161567481614a9f565b835260209283019201615661565b509195945050505050565b600061018082840312156156a057600080fd5b6156a86144f9565b8251600381106156b757600080fd5b81526156c5602084016155f2565b60208201526156d660408401615601565b60408201526156e76060840161560c565b60608201526156f86080840161560c565b608082015261570a8460a08501615617565b60a0820152610160929092015160c083015250919050565b600181811c9082168061573657607f821691505b6020821081141561575757634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561576f57600080fd5b5051919050565b6000808335601e1984360301811261578d57600080fd5b8301803591506001600160401b038211156157a757600080fd5b602001915060608102360382131561447f57600080fd5b600080835481600182811c9150808316806157da57607f831692505b60208084108214156157fa57634e487b7160e01b86526022600452602486fd5b81801561580e576001811461581f5761584c565b60ff1986168952848901965061584c565b60008a81526020902060005b868110156158445781548b82015290850190830161582b565b505084890196505b509498975050505050505050565b6020808252601390820152724c6567696f6e206973206e6f7420796f75727360681b604082015260600190565b600060ff821660ff84168060ff038211156158a4576158a4614c5d565b019392505050565b60208082526025908201527f4c6567696f6e206e6f74206869676820656e6f756768207175657374696e67206040820152641b195d995b60da1b606082015260800190565b600060ff821660ff81141561590857615908614c5d565b60010192915050565b6000808335601e1984360301811261592857600080fd5b8301803591506001600160401b0382111561594257600080fd5b60200191503681900382131561447f57600080fd5b60006020828403121561596957600080fd5b813561347081614a9f565b600060ff821660ff84168082101561598e5761598e614c5d565b90039392505050565b600082198211156159aa576159aa614c5d565b500190565b81835260006001600160fb1b038311156159c857600080fd5b8260051b8083602087013760009401602001938452509192915050565b6001600160a01b0387811682528616602082015260a060408201819052600090615a1290830186886159af565b8281036060840152615a258185876159af565b8381036080909401939093525050600081526020019695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000808335601e19843603018112615a8457600080fd5b83016020810192503590506001600160401b03811115615aa357600080fd5b8060051b360383131561447f57600080fd5b60018060a01b0384168152826020820152606060408201528135606082015260006020830135601e19843603018112615aed57600080fd5b830180356001600160401b03811115615b0557600080fd5b803603851315615b1457600080fd5b60a06080850152615b2d61010085018260208501615a44565b915050615b3c60408501614aae565b60ff1660a0840152615b516060850185615a6d565b605f19808685030160c0870152615b698483856159af565b9350615b786080880188615a6d565b93509150808685030160e087015250615b928383836159af565b98975050505050505050565b6000825160005b81811015615bbf5760208186018101518583015201615ba5565b81811115615bce576000828501525b509190910192915050565b600082615bf657634e487b7160e01b600052601260045260246000fd5b500690565b600060608083018784526020600a8810615c1757615c17614729565b84810188905260408086018490529186905286916080860160005b88811015615c77578435615c4581614a9f565b60ff90811683528585013590615c5a82614a9f565b168285015284830135838301529385019390850190600101615c32565b509a9950505050505050505050565b600060608284031215615c9857600080fd5b604051606081018181106001600160401b0382111715615cba57615cba6144e3565b6040528251615cc881614a9f565b81526020830151615cd881614a9f565b60208201526040830151615ceb81614a74565b60408201529392505050565b600081518084526020808501945080840160005b83811015615d2757815187529582019590820190600101615d0b565b509495945050505050565b6001600160a01b0385811682528416602082015260a060408201819052600090615d5e90830185615cf7565b8281036060840152615d708185615cf7565b838103608090940193909352505060008152602001949350505050565b6001600160a01b03841681526020808201849052606060408084018290528451848301819052600093608092909183870190888401875b82811015615df95781518051855286810151878601528581015186860152880151888501529286019290850190600101615dc4565b50919b9a5050505050505050505050565b600081615e1957615e19614c5d565b506000190190565b600082821015615e3357615e33614c5d565b500390565b600060ff821660ff84168160ff0481118215151615615e5957615e59614c5d565b029392505050565b60ff8416815260608101615e748461473f565b602082019390935260400152919050565b634e487b7160e01b600052603160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220550dfd52c3222a0f30300048dd867317a70e106b9677fbe49dad7abf9687ccc364736f6c63430008090033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.