Source Code
Latest 25 from a total of 1,026 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Supervise Multi | 23569878 | 132 days ago | IN | 0 ETH | 0.0022978 | ||||
| Withdraw Revenue | 23569703 | 132 days ago | IN | 0 ETH | 0.0000264 | ||||
| Withdraw | 22288351 | 311 days ago | IN | 0 ETH | 0.00008869 | ||||
| Withdraw | 17120797 | 1035 days ago | IN | 0 ETH | 0.00268879 | ||||
| Withdraw | 17120782 | 1035 days ago | IN | 0 ETH | 0.00232786 | ||||
| Withdraw | 17120780 | 1035 days ago | IN | 0 ETH | 0.00234991 | ||||
| Withdraw | 17120778 | 1035 days ago | IN | 0 ETH | 0.00235589 | ||||
| Withdraw | 17120775 | 1035 days ago | IN | 0 ETH | 0.00214864 | ||||
| Withdraw | 17120772 | 1035 days ago | IN | 0 ETH | 0.00215784 | ||||
| Withdraw | 17120769 | 1035 days ago | IN | 0 ETH | 0.00226079 | ||||
| Withdraw | 17120768 | 1035 days ago | IN | 0 ETH | 0.00227221 | ||||
| Withdraw | 17120753 | 1035 days ago | IN | 0 ETH | 0.0021692 | ||||
| Withdraw | 17120751 | 1035 days ago | IN | 0 ETH | 0.00225594 | ||||
| Withdraw | 17120747 | 1035 days ago | IN | 0 ETH | 0.00211794 | ||||
| Withdraw | 17120744 | 1035 days ago | IN | 0 ETH | 0.00331808 | ||||
| Withdraw | 17120740 | 1035 days ago | IN | 0 ETH | 0.00211586 | ||||
| Withdraw | 17120737 | 1035 days ago | IN | 0 ETH | 0.00215163 | ||||
| Withdraw | 17120731 | 1035 days ago | IN | 0 ETH | 0.00230941 | ||||
| Withdraw | 17120727 | 1035 days ago | IN | 0 ETH | 0.0023663 | ||||
| Withdraw | 17120725 | 1035 days ago | IN | 0 ETH | 0.00319422 | ||||
| Withdraw | 17120723 | 1035 days ago | IN | 0 ETH | 0.00334235 | ||||
| Withdraw | 17120717 | 1035 days ago | IN | 0 ETH | 0.00245911 | ||||
| Withdraw | 17120711 | 1035 days ago | IN | 0 ETH | 0.00218337 | ||||
| Withdraw | 17120705 | 1035 days ago | IN | 0 ETH | 0.00217344 | ||||
| Withdraw | 17120704 | 1035 days ago | IN | 0 ETH | 0.00327486 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
|||
|---|---|---|---|---|---|---|---|
| Transfer | 23569878 | 132 days ago | 0.011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.0066 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.099 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.0825 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.0033 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.022 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.0011 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.165 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.033 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.00066 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.000002 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.0385 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.022 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.044 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.099 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.022 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.055 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.066 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.022 ETH | ||||
| Transfer | 23569878 | 132 days ago | 0.22 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
LuckyNFT
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2022-12-05
*/
// Sources flattened with hardhat v2.9.9 https://hardhat.org
// File @openzeppelin/contracts/utils/Context.sol@v4.8.0
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File @openzeppelin/contracts/access/Ownable.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File @openzeppelin/contracts/utils/math/SafeMath.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.8.0
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
// File @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.6.0) (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 IERC721Receiver {
/**
* @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 `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File @chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol@v0.4.1
pragma solidity ^0.8.0;
interface VRFCoordinatorV2Interface {
/**
* @notice Get configuration relevant for making requests
* @return minimumRequestConfirmations global min for request confirmations
* @return maxGasLimit global max for request gas limit
* @return s_provingKeyHashes list of registered key hashes
*/
function getRequestConfig()
external
view
returns (
uint16,
uint32,
bytes32[] memory
);
/**
* @notice Request a set of random words.
* @param keyHash - Corresponds to a particular oracle job which uses
* that key for generating the VRF proof. Different keyHash's have different gas price
* ceilings, so you can select a specific one to bound your maximum per request cost.
* @param subId - The ID of the VRF subscription. Must be funded
* with the minimum subscription balance required for the selected keyHash.
* @param minimumRequestConfirmations - How many blocks you'd like the
* oracle to wait before responding to the request. See SECURITY CONSIDERATIONS
* for why you may want to request more. The acceptable range is
* [minimumRequestBlockConfirmations, 200].
* @param callbackGasLimit - How much gas you'd like to receive in your
* fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords
* may be slightly less than this amount because of gas used calling the function
* (argument decoding etc.), so you may need to request slightly more than you expect
* to have inside fulfillRandomWords. The acceptable range is
* [0, maxGasLimit]
* @param numWords - The number of uint256 random values you'd like to receive
* in your fulfillRandomWords callback. Note these numbers are expanded in a
* secure way by the VRFCoordinator from a single random value supplied by the oracle.
* @return requestId - A unique identifier of the request. Can be used to match
* a request to a response in fulfillRandomWords.
*/
function requestRandomWords(
bytes32 keyHash,
uint64 subId,
uint16 minimumRequestConfirmations,
uint32 callbackGasLimit,
uint32 numWords
) external returns (uint256 requestId);
/**
* @notice Create a VRF subscription.
* @return subId - A unique subscription id.
* @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
* @dev Note to fund the subscription, use transferAndCall. For example
* @dev LINKTOKEN.transferAndCall(
* @dev address(COORDINATOR),
* @dev amount,
* @dev abi.encode(subId));
*/
function createSubscription() external returns (uint64 subId);
/**
* @notice Get a VRF subscription.
* @param subId - ID of the subscription
* @return balance - LINK balance of the subscription in juels.
* @return reqCount - number of requests for this subscription, determines fee tier.
* @return owner - owner of the subscription.
* @return consumers - list of consumer address which are able to use this subscription.
*/
function getSubscription(uint64 subId)
external
view
returns (
uint96 balance,
uint64 reqCount,
address owner,
address[] memory consumers
);
/**
* @notice Request subscription owner transfer.
* @param subId - ID of the subscription
* @param newOwner - proposed new owner of the subscription
*/
function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;
/**
* @notice Request subscription owner transfer.
* @param subId - ID of the subscription
* @dev will revert if original owner of subId has
* not requested that msg.sender become the new owner.
*/
function acceptSubscriptionOwnerTransfer(uint64 subId) external;
/**
* @notice Add a consumer to a VRF subscription.
* @param subId - ID of the subscription
* @param consumer - New consumer which can use the subscription
*/
function addConsumer(uint64 subId, address consumer) external;
/**
* @notice Remove a consumer from a VRF subscription.
* @param subId - ID of the subscription
* @param consumer - Consumer to remove from the subscription
*/
function removeConsumer(uint64 subId, address consumer) external;
/**
* @notice Cancel a subscription
* @param subId - ID of the subscription
* @param to - Where to send the remaining LINK to
*/
function cancelSubscription(uint64 subId, address to) external;
}
// File @chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol@v0.4.1
pragma solidity ^0.8.4;
/** ****************************************************************************
* @notice Interface for contracts using VRF randomness
* *****************************************************************************
* @dev PURPOSE
*
* @dev Reggie the Random Oracle (not his real job) wants to provide randomness
* @dev to Vera the verifier in such a way that Vera can be sure he's not
* @dev making his output up to suit himself. Reggie provides Vera a public key
* @dev to which he knows the secret key. Each time Vera provides a seed to
* @dev Reggie, he gives back a value which is computed completely
* @dev deterministically from the seed and the secret key.
*
* @dev Reggie provides a proof by which Vera can verify that the output was
* @dev correctly computed once Reggie tells it to her, but without that proof,
* @dev the output is indistinguishable to her from a uniform random sample
* @dev from the output space.
*
* @dev The purpose of this contract is to make it easy for unrelated contracts
* @dev to talk to Vera the verifier about the work Reggie is doing, to provide
* @dev simple access to a verifiable source of randomness. It ensures 2 things:
* @dev 1. The fulfillment came from the VRFCoordinator
* @dev 2. The consumer contract implements fulfillRandomWords.
* *****************************************************************************
* @dev USAGE
*
* @dev Calling contracts must inherit from VRFConsumerBase, and can
* @dev initialize VRFConsumerBase's attributes in their constructor as
* @dev shown:
*
* @dev contract VRFConsumer {
* @dev constructor(<other arguments>, address _vrfCoordinator, address _link)
* @dev VRFConsumerBase(_vrfCoordinator) public {
* @dev <initialization with other arguments goes here>
* @dev }
* @dev }
*
* @dev The oracle will have given you an ID for the VRF keypair they have
* @dev committed to (let's call it keyHash). Create subscription, fund it
* @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface
* @dev subscription management functions).
* @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations,
* @dev callbackGasLimit, numWords),
* @dev see (VRFCoordinatorInterface for a description of the arguments).
*
* @dev Once the VRFCoordinator has received and validated the oracle's response
* @dev to your request, it will call your contract's fulfillRandomWords method.
*
* @dev The randomness argument to fulfillRandomWords is a set of random words
* @dev generated from your requestId and the blockHash of the request.
*
* @dev If your contract could have concurrent requests open, you can use the
* @dev requestId returned from requestRandomWords to track which response is associated
* @dev with which randomness request.
* @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind,
* @dev if your contract could have multiple requests in flight simultaneously.
*
* @dev Colliding `requestId`s are cryptographically impossible as long as seeds
* @dev differ.
*
* *****************************************************************************
* @dev SECURITY CONSIDERATIONS
*
* @dev A method with the ability to call your fulfillRandomness method directly
* @dev could spoof a VRF response with any random value, so it's critical that
* @dev it cannot be directly called by anything other than this base contract
* @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
*
* @dev For your users to trust that your contract's random behavior is free
* @dev from malicious interference, it's best if you can write it so that all
* @dev behaviors implied by a VRF response are executed *during* your
* @dev fulfillRandomness method. If your contract must store the response (or
* @dev anything derived from it) and use it later, you must ensure that any
* @dev user-significant behavior which depends on that stored value cannot be
* @dev manipulated by a subsequent VRF request.
*
* @dev Similarly, both miners and the VRF oracle itself have some influence
* @dev over the order in which VRF responses appear on the blockchain, so if
* @dev your contract could have multiple VRF requests in flight simultaneously,
* @dev you must ensure that the order in which the VRF responses arrive cannot
* @dev be used to manipulate your contract's user-significant behavior.
*
* @dev Since the block hash of the block which contains the requestRandomness
* @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
* @dev miner could, in principle, fork the blockchain to evict the block
* @dev containing the request, forcing the request to be included in a
* @dev different block with a different hash, and therefore a different input
* @dev to the VRF. However, such an attack would incur a substantial economic
* @dev cost. This cost scales with the number of blocks the VRF oracle waits
* @dev until it calls responds to a request. It is for this reason that
* @dev that you can signal to an oracle you'd like them to wait longer before
* @dev responding to the request (however this is not enforced in the contract
* @dev and so remains effective only in the case of unmodified oracle software).
*/
abstract contract VRFConsumerBaseV2 {
error OnlyCoordinatorCanFulfill(address have, address want);
address private immutable vrfCoordinator;
/**
* @param _vrfCoordinator address of VRFCoordinator contract
*/
constructor(address _vrfCoordinator) {
vrfCoordinator = _vrfCoordinator;
}
/**
* @notice fulfillRandomness handles the VRF response. Your contract must
* @notice implement it. See "SECURITY CONSIDERATIONS" above for important
* @notice principles to keep in mind when implementing your fulfillRandomness
* @notice method.
*
* @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this
* @dev signature, and will call it once it has verified the proof
* @dev associated with the randomness. (It is triggered via a call to
* @dev rawFulfillRandomness, below.)
*
* @param requestId The Id initially returned by requestRandomness
* @param randomWords the VRF output expanded to the requested number of words
*/
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;
// rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
// proof. rawFulfillRandomness then calls fulfillRandomness, after validating
// the origin of the call
function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
if (msg.sender != vrfCoordinator) {
revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator);
}
fulfillRandomWords(requestId, randomWords);
}
}
// File @openzeppelin/contracts/utils/structs/EnumerableSet.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
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.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// 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) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// 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;
/// @solidity memory-safe-assembly
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 in 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;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}
// File @openzeppelin/contracts/utils/structs/EnumerableMap.sol@v4.8.0
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.
pragma solidity ^0.8.0;
/**
* @dev Library for managing an enumerable variant of Solidity's
* https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
* type.
*
* Maps have the following properties:
*
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableMap for EnumerableMap.UintToAddressMap;
*
* // Declare a set state variable
* EnumerableMap.UintToAddressMap private myMap;
* }
* ```
*
* The following map types are supported:
*
* - `uint256 -> address` (`UintToAddressMap`) since v3.0.0
* - `address -> uint256` (`AddressToUintMap`) since v4.6.0
* - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0
* - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0
* - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableMap.
* ====
*/
library EnumerableMap {
using EnumerableSet for EnumerableSet.Bytes32Set;
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Map type with
// bytes32 keys and values.
// The Map implementation uses private functions, and user-facing
// implementations (such as Uint256ToAddressMap) are just wrappers around
// the underlying Map.
// This means that we can only create new EnumerableMaps for types that fit
// in bytes32.
struct Bytes32ToBytes32Map {
// Storage of keys
EnumerableSet.Bytes32Set _keys;
mapping(bytes32 => bytes32) _values;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
Bytes32ToBytes32Map storage map,
bytes32 key,
bytes32 value
) internal returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
/**
* @dev Removes a key-value pair from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {
return map._keys.contains(key);
}
/**
* @dev Returns the number of key-value pairs in the map. O(1).
*/
function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {
return map._keys.length();
}
/**
* @dev Returns the key-value pair stored at position `index` in the map. O(1).
*
* Note that there are no guarantees on the ordering of entries inside the
* array, and it may change when more entries are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {
bytes32 key = map._keys.at(index);
return (key, map._values[key]);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {
bytes32 value = map._values[key];
if (value == bytes32(0)) {
return (contains(map, key), bytes32(0));
} else {
return (true, value);
}
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key");
return value;
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
Bytes32ToBytes32Map storage map,
bytes32 key,
string memory errorMessage
) internal view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || contains(map, key), errorMessage);
return value;
}
// UintToUintMap
struct UintToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
UintToUintMap storage map,
uint256 key,
uint256 value
) internal returns (bool) {
return set(map._inner, bytes32(key), bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element 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(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (uint256(key), uint256(value));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {
(bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
return (success, uint256(value));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(key)));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
UintToUintMap storage map,
uint256 key,
string memory errorMessage
) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(key), errorMessage));
}
// UintToAddressMap
struct UintToAddressMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
UintToAddressMap storage map,
uint256 key,
address value
) internal returns (bool) {
return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToAddressMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element 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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(get(map._inner, bytes32(key)))));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
UintToAddressMap storage map,
uint256 key,
string memory errorMessage
) internal view returns (address) {
return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));
}
// AddressToUintMap
struct AddressToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
AddressToUintMap storage map,
address key,
uint256 value
) internal returns (bool) {
return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(AddressToUintMap storage map, address key) internal returns (bool) {
return remove(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(AddressToUintMap storage map, address key) internal view returns (bool) {
return contains(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(AddressToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element 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(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (address(uint160(uint256(key))), uint256(value));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {
(bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));
return (success, uint256(value));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(AddressToUintMap storage map, address key) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
AddressToUintMap storage map,
address key,
string memory errorMessage
) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));
}
// Bytes32ToUintMap
struct Bytes32ToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
Bytes32ToUintMap storage map,
bytes32 key,
uint256 value
) internal returns (bool) {
return set(map._inner, key, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {
return remove(map._inner, key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {
return contains(map._inner, key);
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(Bytes32ToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element 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(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (key, uint256(value));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {
(bool success, bytes32 value) = tryGet(map._inner, key);
return (success, uint256(value));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {
return uint256(get(map._inner, key));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
Bytes32ToUintMap storage map,
bytes32 key,
string memory errorMessage
) internal view returns (uint256) {
return uint256(get(map._inner, key, errorMessage));
}
}
// File contracts/Crowdfund.sol
pragma solidity ^0.8.0;
enum CrowdfundStatus{ OnSale, Traded, PrizeDrawn, Expired, Stopped }
struct Crowdfund {
address creator;
address asset;
uint factor;
uint sharePriceWithoutFactor;
uint sharePrice;
uint expirationTime;
uint supervisionTime;
bool supervised;
uint soldShares;
EnumerableMap.AddressToUintMap participants;
uint proxyId;
uint tokenId;
uint tradePrice;
uint tradeShares;
uint changePerShare;
uint revenue;
uint randNum;
bool cashedNFT;
mapping(address => bool) cashedChange;
CrowdfundStatus status;
}
struct CrowdfundGetInfo {
address creator;
address asset;
uint factor;
uint sharePriceWithoutFactor;
uint sharePrice;
uint expirationTime;
uint supervisionTime;
bool supervised;
uint soldShares;
uint proxyId;
uint tokenId;
uint tradePrice;
uint tradeShares;
uint changePerShare;
uint revenue;
uint randNum;
bool cashedNFT;
CrowdfundStatus status;
}
struct TradeBaseInfo {
address asset;
uint tokenId;
uint tradePrice;
}
// File contracts/interface/IProxy.sol
pragma solidity ^0.8.0;
interface IProxy {
function buyNFT(TradeBaseInfo calldata crowdfundInfo, bytes calldata data) external payable;
}
// File contracts/Utils.sol
pragma solidity ^0.8.0;
library MoneyUtils {
function transferInMoneyFromSender(address token, uint amount)
internal
{
if (amount > 0) {
if (token == address(0)) {
require(msg.value >= amount, "not enough");
} else {
require(IERC20(token).transferFrom(msg.sender, address(this), amount), "transfer in money fail");
}
}
}
}
library RevertUtils {
/// Reverts, forwarding the return data from the last external call.
/// If there was no preceding external call, reverts with empty returndata.
/// It's up to the caller to ensure that the preceding call actually reverted - if it did not,
/// the return data will come from a successfull call.
///
/// @dev This function writes to arbitrary memory locations, violating any assumptions the compiler
/// might have about memory use. This may prevent it from doing some kinds of memory optimizations
/// planned in future versions or make them unsafe. It's recommended to obtain the revert data using
/// the try/catch statement and rethrow it with `rawRevert()` instead.
function forwardRevert() internal pure {
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
/// Reverts, directly setting the return data from the provided `bytes` object.
/// Unlike the high-level `revert` statement, this allows forwarding the revert data obtained from
/// a failed external call (high-level `revert` would wrap it in an `Error`).
///
/// @dev This function is recommended over `forwardRevert()` because it does not interfere with
/// the memory allocation mechanism used by the compiler.
function rawRevert(bytes memory revertData) internal pure {
assembly {
// NOTE: `bytes` arrays in memory start with a 32-byte size slot, which is followed by data.
let revertDataStart := add(revertData, 32)
let revertDataEnd := add(revertDataStart, mload(revertData))
revert(revertDataStart, revertDataEnd)
}
}
}
//library SendUtils {
// error EtherTransferFailed();
//
// function _sendEthViaCall(address payable receiver, uint amount) internal {
// if (amount > 0) {
// (bool success, ) = receiver.call{value: amount}("");
// if (!success)
// revert EtherTransferFailed();
// }
// }
//
// function _returnAllEth() internal {
// // NOTE: This works on the assumption that the whole balance of the contract consists of
// // the ether sent by the caller.
// // (1) This is never 100% true because anyone can send ether to it with selfdestruct or by using
// // its address as the coinbase when mining a block. Anyone doing that is doing it to their own
// // disavantage though so we're going to disregard these possibilities.
// // (2) For this to be safe we must ensure that no ether is stored in the contract long-term.
// // It's best if it has no receive function and all payable functions should ensure that they
// // use the whole balance or send back the remainder.
// _sendEthViaCall(payable(msg.sender), address(this).balance);
// }
//
// function _returnAllToken() internal {
// _sendEthViaCall(payable(msg.sender), address(this).balance);
// }
//}
// File contracts/LuckyNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract LuckyNFT is Ownable, IERC721Receiver, ReentrancyGuard, VRFConsumerBaseV2 {
using SafeMath for uint;
using EnumerableMap for EnumerableMap.AddressToUintMap;
uint constant MAX_UINT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
address public treasury;
address public trader;
uint public revenue;
bool public open;
uint public factor = 11000;
uint constant factorBase = 10000;
uint public supervisionLockTime = 90 days;
uint public nextProxyId = 1;
mapping(uint => address) public proxies;
mapping(uint => bool) public proxyStatus;
uint public nextCrowdfundId = 1;
mapping(uint => Crowdfund) internal crowdfunds;
mapping(address => bool) public assets;
address public vrfCoordinator;
uint64 public vrfSubId;
bytes32 public vrfKeyHash;
uint32 public vrfCBGasLimit;
uint16 constant vrfReqConfirm = 3;
uint32 constant vrfNumWords = 1;
mapping(uint => uint) public vrfRequestIds;
// event
event Proxy(address proxy, uint id, bool status);
event Asset(address asset, bool status);
event NewCrowdfund(uint crowdfundId, address asset, uint sharePriceWithoutFactor, uint expirationTime);
event StatusChanged(uint crowdfundId, CrowdfundStatus status);
event Sold(uint crowdfundId, address user, uint quantity);
event NewRevenue(uint crowdfundId, uint newRevenue);
event CasedPrize(uint crowdfundId, address winner, address nft, uint tokenId);
event GotChange(uint crowdfundId, address user, uint amount);
event Withdrawn(uint crowdfundId, address user, uint shareQuantity, uint anount);
event SupervisionLockTimeChanged(uint supervisionLockTime);
event SupervisedNFT(uint crowdfundId, address to, address nft, uint tokenId);
event SupervisedETH(uint crowdfundId, address to, uint anount);
// modifier
modifier onlyOpening() {
require(open, "only opening");
_;
}
modifier onlyTreasury() {
require(msg.sender == treasury, "only treasury");
_;
}
modifier onlyTrader() {
require(msg.sender == trader, "only trader");
_;
}
constructor(
address treasury_,
address trader_,
address vrfCoordinator_,
uint64 vrfSubId_,
bytes32 vrfKeyHash_,
uint32 vrfCBGasLimit_
)
VRFConsumerBaseV2(vrfCoordinator_)
{
treasury = treasury_;
trader = trader_;
vrfCoordinator = vrfCoordinator_;
vrfSubId = vrfSubId_;
vrfKeyHash = vrfKeyHash_;
vrfCBGasLimit = vrfCBGasLimit_;
}
function SetOpen(
bool open_
)
external
onlyOwner
{
open = open_;
}
function SetFactor(
uint factor_
)
external
onlyOwner
{
require(factor_ >= factorBase, "invalid factor");
factor = factor_;
}
function setSupervisionLockTime(
uint supervisionLockTime_
)
external
onlyOwner
{
require(supervisionLockTime_ != 0, "invalid supervision lock time");
supervisionLockTime = supervisionLockTime_;
emit SupervisionLockTimeChanged(supervisionLockTime);
}
function SetTreasury(
address treasury_
)
external
onlyOwner
{
treasury = treasury_;
}
function SetTrader(
address trader_
)
external
onlyOwner
{
trader = trader_;
}
function RegisterProxy(
address proxy
)
external
onlyOwner
{
proxies[nextProxyId] = proxy;
proxyStatus[nextProxyId] = true;
emit Proxy(proxy, nextProxyId, true);
nextProxyId++;
}
function UnregisterProxy(
uint id
)
external
onlyOwner
{
require(id != 0 && id < nextProxyId, "invalid proxy id");
require(proxyStatus[id], "unregisted already");
proxyStatus[id] = false;
emit Proxy(proxies[id], id, false);
}
function RegisterAsset(
address asset
)
external
onlyOwner
{
assets[asset] = true;
emit Asset(asset, true);
}
function UnregisterAsset(
address asset
)
external
onlyOwner
{
assets[asset] = false;
emit Asset(asset, false);
}
function SetChainlinkVRF(
address vrfCoordinator_,
bytes32 keyHash_,
uint32 callbackGasLimit_,
uint64 subscriptionId_
)
external
onlyOwner
{
vrfCoordinator = vrfCoordinator_;
vrfKeyHash = keyHash_;
vrfCBGasLimit = callbackGasLimit_;
vrfSubId = subscriptionId_;
}
function WithdrawRevenue(
address to,
uint amount
)
external
onlyTreasury
{
require(amount <= revenue, "invalid amount");
revenue -= amount;
payable(to).transfer(amount);
}
function Supervise(
uint crowdfundId,
address to
)
external
onlyTreasury
{
doSupervise_(crowdfundId, to);
}
function SuperviseMulti(
uint[] memory crowdfundIds,
address to
)
external
onlyTreasury
{
for (uint i = 0; i < crowdfundIds.length; i++) {
doSupervise_(crowdfundIds[i], to);
}
}
function CreateCrowdfund(
address asset,
uint sharePriceWithoutFactor,
uint expirationTime,
uint buyQuantity
)
external
payable
onlyOpening
nonReentrant
{
require(asset != address(0), "invalid asset");
require(assets[asset], "asset unregistered");
require(sharePriceWithoutFactor != 0, "invalid share price");
require(block.timestamp < expirationTime, "invalid expiration time");
require(buyQuantity != 0, "invalid buy shares");
Crowdfund storage crowdfund = crowdfunds[nextCrowdfundId];
crowdfund.creator = msg.sender;
crowdfund.factor = factor;
crowdfund.asset = asset;
crowdfund.sharePriceWithoutFactor = sharePriceWithoutFactor;
crowdfund.expirationTime = expirationTime;
crowdfund.supervisionTime = MAX_UINT;
crowdfund.status = CrowdfundStatus.OnSale;
(bool suc, uint sharePrice) = sharePriceWithoutFactor.tryMul(factor);
require(suc, "uint tryMul fail");
sharePrice = sharePrice.div(factorBase);
crowdfund.sharePrice = sharePrice;
emit NewCrowdfund(nextCrowdfundId, asset, sharePriceWithoutFactor, expirationTime);
emit StatusChanged(nextCrowdfundId, CrowdfundStatus.OnSale);
buyShares_(nextCrowdfundId, crowdfund, buyQuantity);
nextCrowdfundId++;
}
function BuyShares(
uint crowdfundId,
uint buyQuantity
)
external
payable
onlyOpening
nonReentrant
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(block.timestamp < crowdfund.expirationTime, "expired");
require(crowdfund.status == CrowdfundStatus.OnSale, "invalid crowdfund status");
require(buyQuantity != 0, "invalid buy quantity");
buyShares_(crowdfundId, crowdfund, buyQuantity);
}
function Trade(
uint crowdfundId,
uint proxyId,
uint tokenId,
uint tradePrice,
bytes calldata data
)
external
onlyTrader
nonReentrant
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(block.timestamp < crowdfund.expirationTime, "expired");
require(crowdfund.status == CrowdfundStatus.OnSale, "invalid crowdfund status");
require(assets[crowdfund.asset], "invalid asset");
require(tradePrice <= crowdfund.sharePriceWithoutFactor.mul(crowdfund.soldShares), "invalid trade price");
require(IERC721(crowdfund.asset).ownerOf(tokenId) != address(this), "have owned NFT already");
address proxy = proxies[proxyId];
require(proxy != address(0), "invalid proxy address");
require(proxyStatus[proxyId], "invalid proxy status");
TradeBaseInfo memory baseInfo = TradeBaseInfo(
crowdfund.asset,
tokenId,
tradePrice
);
try IProxy(proxy).buyNFT{value: tradePrice}(
baseInfo,
data
) {
require(IERC721(baseInfo.asset).ownerOf(tokenId) == address(this), "dont own NFT");
crowdfund.status = CrowdfundStatus.Traded;
crowdfund.supervisionTime = block.timestamp + supervisionLockTime;
crowdfund.proxyId = proxyId;
crowdfund.tokenId = tokenId;
crowdfund.tradePrice = tradePrice;
updateRevenue_(crowdfundId, crowdfund);
uint requestId = VRFCoordinatorV2Interface(vrfCoordinator).requestRandomWords(
vrfKeyHash,
vrfSubId,
vrfReqConfirm,
vrfCBGasLimit,
vrfNumWords
);
vrfRequestIds[requestId] = crowdfundId;
} catch (bytes memory lowLevelData) {
RevertUtils.rawRevert(lowLevelData);
}
}
function CashPrize(
uint crowdfundId
)
external
nonReentrant
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(!crowdfund.supervised, "have moved to treasury");
require(crowdfund.status == CrowdfundStatus.PrizeDrawn, "invalid crowdfund status");
address winner = fixWinner_(crowdfund);
require(msg.sender == winner, "is not winner");
// transfer nft
if (!crowdfund.cashedNFT) {
crowdfund.cashedNFT = true;
IERC721(crowdfund.asset).transferFrom(address(this), winner, crowdfund.tokenId);
emit CasedPrize(crowdfundId, winner, crowdfund.asset, crowdfund.tokenId);
}
// transfer change
if (!crowdfund.cashedChange[winner]) {
uint shareQuantity;
(, shareQuantity) = crowdfund.participants.tryGet(winner);
(bool suc, uint change) = shareQuantity.tryMul(crowdfund.changePerShare);
require(suc, "tryMul fail");
crowdfund.cashedChange[winner] = true;
if (change > 0) {
payable(winner).transfer(change);
}
emit GotChange(crowdfundId, winner, change);
}
}
function GetChange(
uint crowdfundId
)
external
nonReentrant
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(crowdfund.status == CrowdfundStatus.PrizeDrawn, "invalid crowdfund status");
require(!crowdfund.supervised, "have moved to treasury");
require(!crowdfund.cashedChange[msg.sender], "have gotten change already");
getOneCrowdfundChange_(crowdfundId, crowdfund);
}
function GetMultiChanges(
uint[] calldata crowdfundIds
)
external
nonReentrant
{
for (uint i = 0; i < crowdfundIds.length; i++) {
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundIds[i]);
require(crowdfund.status == CrowdfundStatus.PrizeDrawn, "invalid crowdfund status");
require(!crowdfund.supervised, "have moved to treasury");
require(!crowdfund.cashedChange[msg.sender], "have gotten change already");
getOneCrowdfundChange_(crowdfundIds[i], crowdfund);
}
}
function Withdraw(
uint crowdfundId
)
external
nonReentrant
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(!crowdfund.supervised, "have moved to treasury");
checkExpiration_(crowdfundId, crowdfund);
require(crowdfund.status == CrowdfundStatus.Expired || crowdfund.status == CrowdfundStatus.Stopped, "invalid crowdfund status");
require(!crowdfund.cashedChange[msg.sender], "have withdrawn already");
(bool suc, uint shareQuantity) = crowdfund.participants.tryGet(msg.sender);
require(suc, "is not participant");
uint money;
(suc, money) = shareQuantity.tryMul(crowdfund.sharePrice);
require(suc, "tryMul fail");
crowdfund.cashedChange[msg.sender] = true;
payable(msg.sender).transfer(money);
emit Withdrawn(crowdfundId, msg.sender, shareQuantity, money);
}
function Stop(
uint crowdfundId
)
external
onlyOwner
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(crowdfund.status == CrowdfundStatus.OnSale, "invalid crowdfund status");
crowdfund.status = CrowdfundStatus.Stopped;
crowdfund.supervisionTime = block.timestamp + supervisionLockTime;
emit StatusChanged(crowdfundId, CrowdfundStatus.Stopped);
}
function GetCrowdfund(
uint crowdfundId
)
public
view
returns (CrowdfundGetInfo memory)
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
CrowdfundGetInfo memory info = CrowdfundGetInfo(
crowdfund.creator,
crowdfund.asset,
crowdfund.factor,
crowdfund.sharePriceWithoutFactor,
crowdfund.sharePrice,
crowdfund.expirationTime,
crowdfund.supervisionTime,
crowdfund.supervised,
crowdfund.soldShares,
crowdfund.proxyId,
crowdfund.tokenId,
crowdfund.tradePrice,
crowdfund.tradeShares,
crowdfund.changePerShare,
crowdfund.revenue,
crowdfund.randNum,
crowdfund.cashedNFT,
crowdfund.status
);
if (crowdfund.status == CrowdfundStatus.OnSale && block.timestamp >= crowdfund.expirationTime) {
info.status = CrowdfundStatus.Expired;
info.supervisionTime = crowdfund.expirationTime + supervisionLockTime;
}
return info;
}
function GetShareQuantity(
uint crowdfundId,
address user
)
public
view
returns (uint)
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
uint value;
(, value) = crowdfund.participants.tryGet(user);
return value;
}
function GetPrize(
uint crowdfundId
)
public
view
returns (CrowdfundStatus, address, uint)
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
if (crowdfund.status != CrowdfundStatus.PrizeDrawn) {
return (crowdfund.status, address(0), 0);
}
address winner = fixWinner_(crowdfund);
return (CrowdfundStatus.PrizeDrawn, winner, crowdfund.changePerShare);
}
function GetUserPrize(
uint crowdfundId,
address user
)
public
view
returns (CrowdfundStatus, bool, uint, bool)
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
bool isWinner = false;
if (crowdfund.status == CrowdfundStatus.PrizeDrawn) {
isWinner = fixWinner_(crowdfund) == user;
}
uint shareQuantity;
(, shareQuantity) = crowdfund.participants.tryGet(user);
uint changeValue = 0;
if (crowdfund.status == CrowdfundStatus.PrizeDrawn) {
changeValue = shareQuantity.mul(crowdfund.changePerShare);
} else if (crowdfund.status > CrowdfundStatus.PrizeDrawn) {
changeValue = shareQuantity.mul(crowdfund.sharePrice);
}
return (crowdfund.status, isWinner, changeValue, crowdfund.cashedChange[user]);
}
function GetSuperviseAssets(
uint crowdfundId
)
public
view
returns (bool, uint) {
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
if (crowdfund.supervised) {
return (false, 0);
}
if (block.timestamp >= crowdfund.supervisionTime
|| (crowdfund.status == CrowdfundStatus.OnSale
&& block.timestamp >= (crowdfund.expirationTime + supervisionLockTime)))
{
bool leftNFT = (crowdfund.status == CrowdfundStatus.Traded
|| crowdfund.status == CrowdfundStatus.PrizeDrawn)
&& (!crowdfund.cashedNFT);
uint leftAmount = getLeftETHAmount_(crowdfund);
return (leftNFT, leftAmount);
}
return (false, 0);
}
// --------------- internal functions ---------------
function doSupervise_(
uint crowdfundId,
address to
)
internal
{
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
require(!crowdfund.supervised, "have moved to treasury");
checkExpiration_(crowdfundId, crowdfund);
require(block.timestamp >= crowdfund.supervisionTime, "not yet supervision time");
crowdfund.supervised = true;
// transfer nft
bool leftNFT = (crowdfund.status == CrowdfundStatus.Traded
|| crowdfund.status == CrowdfundStatus.PrizeDrawn)
&& (!crowdfund.cashedNFT);
if (leftNFT) {
IERC721(crowdfund.asset).transferFrom(address(this), to, crowdfund.tokenId);
emit SupervisedNFT(crowdfundId, to, crowdfund.asset, crowdfund.tokenId);
}
// transfer ETH
uint leftAmount = getLeftETHAmount_(crowdfund);
if (leftAmount > 0) {
payable(to).transfer(leftAmount);
emit SupervisedETH(crowdfundId, to, leftAmount);
}
}
function buyShares_(
uint crowdfundId,
Crowdfund storage crowdfund,
uint quantity
)
internal
{
bool suc;
(suc, crowdfund.soldShares) = crowdfund.soldShares.tryAdd(quantity);
require(suc, "invalid quantity");
uint amount;
(suc, amount) = crowdfund.sharePrice.tryMul(quantity);
require(suc, "invalid quantity");
MoneyUtils.transferInMoneyFromSender(address(0), amount);
uint userBuy;
(, userBuy) = crowdfund.participants.tryGet(msg.sender);
(suc, userBuy) = userBuy.tryAdd(quantity);
require(suc, "invalid quantity");
crowdfund.participants.set(msg.sender, userBuy);
emit Sold(crowdfundId, msg.sender, quantity);
}
function getCrowdfundFromId_(
uint crowdfundId
)
internal
view
returns (Crowdfund storage)
{
require(crowdfundId > 0 && crowdfundId < nextCrowdfundId, "invalid crowdfund id");
Crowdfund storage crowdfund = crowdfunds[crowdfundId];
return crowdfund;
}
function fixWinner_(
Crowdfund storage crowdfund
)
internal
view
returns (address)
{
address user;
uint value;
uint offset = crowdfund.randNum%crowdfund.soldShares + 1;
uint length = crowdfund.participants.length();
for (uint i = 0; i < length-1; i++) {
(user, value) = crowdfund.participants.at(i);
if (offset <= value) {
return user;
}
offset -= value;
continue;
}
(user,) = crowdfund.participants.at(length-1);
return user;
}
function updateRevenue_(
uint crowdfundId,
Crowdfund storage crowdfund
)
internal
{
(bool suc, uint tradeShares) = crowdfund.tradePrice.tryDiv(crowdfund.sharePriceWithoutFactor);
require(suc, "trySub fail");
if (crowdfund.tradePrice % crowdfund.sharePriceWithoutFactor != 0) {
tradeShares++;
}
uint totalChange;
(suc, totalChange) = (crowdfund.soldShares - tradeShares).tryMul(crowdfund.sharePrice);
require(suc, "tryMul fail");
uint changePerShare;
(suc, changePerShare) = totalChange.tryDiv(crowdfund.soldShares);
require(suc, "tryDiv fail");
uint totalMoney;
(suc, totalMoney) = crowdfund.soldShares.tryMul(crowdfund.sharePrice);
uint newRevenue;
(suc, newRevenue) = totalMoney.trySub(changePerShare.mul(crowdfund.soldShares).add(crowdfund.tradePrice));
require(suc, "trySub fail");
(suc, revenue) = revenue.tryAdd(newRevenue);
require(suc, "tryAdd fail");
crowdfund.tradeShares = tradeShares;
crowdfund.changePerShare = changePerShare;
crowdfund.revenue = newRevenue;
emit NewRevenue(crowdfundId, newRevenue);
}
function checkExpiration_(
uint crowdfundId,
Crowdfund storage crowdfund
)
internal
{
if (crowdfund.status == CrowdfundStatus.OnSale && block.timestamp >= crowdfund.expirationTime) {
crowdfund.status = CrowdfundStatus.Expired;
crowdfund.supervisionTime = crowdfund.expirationTime + supervisionLockTime;
emit StatusChanged(crowdfundId, CrowdfundStatus.Expired);
}
}
function getLeftETHAmount_(
Crowdfund storage crowdfund
)
internal
view
returns (uint)
{
uint leftShares;
address user;
uint value;
uint length = crowdfund.participants.length();
for (uint i = 0; i < length; i++)
{
(user, value) = crowdfund.participants.at(i);
if (!crowdfund.cashedChange[user]) {
leftShares += value;
}
}
if (crowdfund.status == CrowdfundStatus.Traded
|| crowdfund.status == CrowdfundStatus.PrizeDrawn)
{
return crowdfund.changePerShare*leftShares;
} else {
return crowdfund.sharePrice*leftShares;
}
}
function getOneCrowdfundChange_(
uint crowdfundId,
Crowdfund storage crowdfund
)
internal
{
(bool suc, uint shareQuantity) = crowdfund.participants.tryGet(msg.sender);
require(suc, "is not participant");
uint change;
(suc, change) = shareQuantity.tryMul(crowdfund.changePerShare);
require(suc, "tryMul fail");
crowdfund.cashedChange[msg.sender] = true;
if (change > 0) {
payable(msg.sender).transfer(change);
}
emit GotChange(crowdfundId, msg.sender, change);
}
// ------------ IERC721Receiver ------------
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
)
external
override
returns (bytes4)
{
operator;
from;
tokenId;
data;
return IERC721Receiver.onERC721Received.selector;
}
// ------------ Chainlink VRF ------------
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
)
internal
override
{
uint crowdfundId = vrfRequestIds[requestId];
require(crowdfundId != 0, "invalid crowdfundId");
Crowdfund storage crowdfund = getCrowdfundFromId_(crowdfundId);
crowdfund.randNum = randomWords[0];
crowdfund.supervisionTime = block.timestamp + supervisionLockTime;
crowdfund.status = CrowdfundStatus.PrizeDrawn;
emit StatusChanged(crowdfundId, CrowdfundStatus.PrizeDrawn);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"address","name":"trader_","type":"address"},{"internalType":"address","name":"vrfCoordinator_","type":"address"},{"internalType":"uint64","name":"vrfSubId_","type":"uint64"},{"internalType":"bytes32","name":"vrfKeyHash_","type":"bytes32"},{"internalType":"uint32","name":"vrfCBGasLimit_","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"Asset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"address","name":"nft","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"CasedPrize","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GotChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"sharePriceWithoutFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expirationTime","type":"uint256"}],"name":"NewCrowdfund","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRevenue","type":"uint256"}],"name":"NewRevenue","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":"proxy","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"Proxy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"Sold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"enum CrowdfundStatus","name":"status","type":"uint8"}],"name":"StatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"anount","type":"uint256"}],"name":"SupervisedETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"nft","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"SupervisedNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"supervisionLockTime","type":"uint256"}],"name":"SupervisionLockTimeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shareQuantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"anount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"internalType":"uint256","name":"buyQuantity","type":"uint256"}],"name":"BuyShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"CashPrize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"sharePriceWithoutFactor","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"buyQuantity","type":"uint256"}],"name":"CreateCrowdfund","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"GetChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"GetCrowdfund","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"factor","type":"uint256"},{"internalType":"uint256","name":"sharePriceWithoutFactor","type":"uint256"},{"internalType":"uint256","name":"sharePrice","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"supervisionTime","type":"uint256"},{"internalType":"bool","name":"supervised","type":"bool"},{"internalType":"uint256","name":"soldShares","type":"uint256"},{"internalType":"uint256","name":"proxyId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"tradePrice","type":"uint256"},{"internalType":"uint256","name":"tradeShares","type":"uint256"},{"internalType":"uint256","name":"changePerShare","type":"uint256"},{"internalType":"uint256","name":"revenue","type":"uint256"},{"internalType":"uint256","name":"randNum","type":"uint256"},{"internalType":"bool","name":"cashedNFT","type":"bool"},{"internalType":"enum CrowdfundStatus","name":"status","type":"uint8"}],"internalType":"struct CrowdfundGetInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"crowdfundIds","type":"uint256[]"}],"name":"GetMultiChanges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"GetPrize","outputs":[{"internalType":"enum CrowdfundStatus","name":"","type":"uint8"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"GetShareQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"GetSuperviseAssets","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"GetUserPrize","outputs":[{"internalType":"enum CrowdfundStatus","name":"","type":"uint8"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"RegisterAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proxy","type":"address"}],"name":"RegisterProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vrfCoordinator_","type":"address"},{"internalType":"bytes32","name":"keyHash_","type":"bytes32"},{"internalType":"uint32","name":"callbackGasLimit_","type":"uint32"},{"internalType":"uint64","name":"subscriptionId_","type":"uint64"}],"name":"SetChainlinkVRF","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"factor_","type":"uint256"}],"name":"SetFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"open_","type":"bool"}],"name":"SetOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"trader_","type":"address"}],"name":"SetTrader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"treasury_","type":"address"}],"name":"SetTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"Stop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"Supervise","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"crowdfundIds","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"SuperviseMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"},{"internalType":"uint256","name":"proxyId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"tradePrice","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"Trade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"UnregisterAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"UnregisterProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crowdfundId","type":"uint256"}],"name":"Withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawRevenue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextCrowdfundId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextProxyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"open","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proxies","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proxyStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"supervisionLockTime_","type":"uint256"}],"name":"setSupervisionLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supervisionLockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trader","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfCBGasLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfCoordinator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfKeyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vrfRequestIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfSubId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a0604052612af86006556276a70060075560016008556001600b553480156200002857600080fd5b5060405162003f8038038062003f808339810160408190526200004b916200014f565b836200005733620000e2565b600180556001600160a01b03908116608052600280549782166001600160a01b0319988916179055600380549682169690971695909517909555600e80546001600160401b03909316600160a01b026001600160e01b0319909316939094169290921717909155600f556010805463ffffffff90921663ffffffff19909216919091179055620001e2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200014a57600080fd5b919050565b60008060008060008060c087890312156200016957600080fd5b620001748762000132565b9550620001846020880162000132565b9450620001946040880162000132565b60608801519094506001600160401b0381168114620001b257600080fd5b608088015160a0890151919450925063ffffffff81168114620001d457600080fd5b809150509295509295509295565b608051613d7b6200020560003960008181610a400152610a820152613d7b6000f3fe6080604052600436106102885760003560e01c80637181160c1161015a578063b71309f8116100c1578063e9fc660d1161007a578063e9fc660d1461086c578063f11b81881461088c578063f2fde38b146108bc578063f628f673146108dc578063fcfff16f146108ef578063ff00148a1461090957600080fd5b8063b71309f81461078b578063beae6e6c146107ab578063cb38e238146107dd578063cb7ef3e5146107fd578063dd07694a1461081d578063e56b9dce1461083d57600080fd5b80639fc5fb2c116101135780639fc5fb2c14610695578063a3e56fa8146106b5578063abd90f85146106d5578063af5cd2421461070b578063b0dd7c521461074b578063b6f50ec01461076b57600080fd5b80637181160c146105d1578063731fb408146105f15780638a0d20ef146106215780638da5cb5b14610641578063910764c91461065f578063985b4dd41461067557600080fd5b8063425c9fa2116101fe57806359be45bc116101b757806359be45bc146105055780635a758cd0146105255780635b6b431d1461055c5780635f13e0c41461057c57806361d027b31461059c578063715018a6146105bc57600080fd5b8063425c9fa21461043557806342a59d27146104625780634418a5051461048f578063447d53be146104af5780634d69c6c6146104cf57806354f703f8146104ef57600080fd5b80631fe543e3116102505780631fe543e31461037557806321f224201461039557806329484706146103a85780632f337fec146103c857806332615640146103de5780633e9491a21461041f57600080fd5b8063041d443e1461028d57806309c50a44146102b6578063150b7a02146102d85780631758078b1461031d5780631d034b2e14610355575b600080fd5b34801561029957600080fd5b506102a3600f5481565b6040519081526020015b60405180910390f35b3480156102c257600080fd5b506102d66102d13660046134e9565b61091f565b005b3480156102e457600080fd5b506103046102f3366004613548565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016102ad565b34801561032957600080fd5b5060035461033d906001600160a01b031681565b6040516001600160a01b0390911681526020016102ad565b34801561036157600080fd5b506102d66103703660046134e9565b6109cb565b34801561038157600080fd5b506102d661039036600461366c565b610a35565b6102d66103a33660046136b3565b610ac2565b3480156103b457600080fd5b506102d66103c33660046136e3565b610be9565b3480156103d457600080fd5b506102a3600b5481565b3480156103ea57600080fd5b50600e5461040690600160a01b900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102ad565b34801561042b57600080fd5b506102a360045481565b34801561044157600080fd5b506102a3610450366004613700565b60116020526000908152604090205481565b34801561046e57600080fd5b5061048261047d366004613700565b610c04565b6040516102ad9190613751565b34801561049b57600080fd5b506102d66104aa366004613700565b610d68565b3480156104bb57600080fd5b506102d66104ca366004613844565b610df5565b3480156104db57600080fd5b506102a36104ea366004613870565b610eb4565b3480156104fb57600080fd5b506102a360065481565b34801561051157600080fd5b506102d66105203660046138a0565b610edd565b34801561053157600080fd5b50610545610540366004613700565b611453565b6040805192151583526020830191909152016102ad565b34801561056857600080fd5b506102d6610577366004613700565b611541565b34801561058857600080fd5b506102d6610597366004613700565b61176a565b3480156105a857600080fd5b5060025461033d906001600160a01b031681565b3480156105c857600080fd5b506102d661187a565b3480156105dd57600080fd5b506102d66105ec36600461390a565b61188e565b3480156105fd57600080fd5b5061061161060c366004613870565b6118ec565b6040516102ad9493929190613973565b34801561062d57600080fd5b506102d661063c36600461399e565b6119fc565b34801561064d57600080fd5b506000546001600160a01b031661033d565b34801561066b57600080fd5b506102a360075481565b34801561068157600080fd5b506102d66106903660046134e9565b611a67565b3480156106a157600080fd5b506102d66106b0366004613700565b611a91565b3480156106c157600080fd5b50600e5461033d906001600160a01b031681565b3480156106e157600080fd5b5061033d6106f0366004613700565b6009602052600090815260409020546001600160a01b031681565b34801561071757600080fd5b5061073b610726366004613700565b600a6020526000908152604090205460ff1681565b60405190151581526020016102ad565b34801561075757600080fd5b506102d66107663660046134e9565b611b79565b34801561077757600080fd5b506102d6610786366004613700565b611bd8565b34801561079757600080fd5b506102d66107a63660046139e5565b611c28565b3480156107b757600080fd5b506010546107c89063ffffffff1681565b60405163ffffffff90911681526020016102ad565b3480156107e957600080fd5b506102d66107f8366004613700565b611d54565b34801561080957600080fd5b506102d66108183660046134e9565b611def565b34801561082957600080fd5b506102d6610838366004613870565b611e19565b34801561084957600080fd5b5061085d610858366004613700565b611e4d565b6040516102ad93929190613a5a565b34801561087857600080fd5b506102d6610887366004613700565b611eb7565b34801561089857600080fd5b5061073b6108a73660046134e9565b600d6020526000908152604090205460ff1681565b3480156108c857600080fd5b506102d66108d73660046134e9565b61218f565b6102d66108ea366004613a82565b612205565b3480156108fb57600080fd5b5060055461073b9060ff1681565b34801561091557600080fd5b506102a360085481565b61092761254a565b60088054600090815260096020908152604080832080546001600160a01b0319166001600160a01b03871690811790915584548452600a835292819020805460ff1916600190811790915593548151938452918301919091528101919091527f4e435dde759dcf9c36050c45daa530f84ca2c3ab65c25980d826c0df56e563109060600160405180910390a1600880549060006109c383613ad3565b919050555050565b6109d361254a565b6001600160a01b0381166000818152600d6020908152604091829020805460ff191660019081179091558251938452908301527ff419c416c0533e46364754aa7bdb0c5adbfce030a8424e1f348ce2cdc6eb89d791015b60405180910390a150565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610ab45760405163073e64fd60e21b81523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b610abe82826125a4565b5050565b60055460ff16610b035760405162461bcd60e51b815260206004820152600c60248201526b6f6e6c79206f70656e696e6760a01b6044820152606401610aab565b610b0b61267b565b6000610b16836126d4565b905080600501544210610b555760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610aab565b6000601582015460ff166004811115610b7057610b70613719565b14610b8d5760405162461bcd60e51b8152600401610aab90613aec565b81600003610bd45760405162461bcd60e51b8152602060048201526014602482015273696e76616c696420627579207175616e7469747960601b6044820152606401610aab565b610bdf83828461273b565b50610abe60018055565b610bf161254a565b6005805460ff1916911515919091179055565b610c0c613423565b6000610c17836126d4565b604080516102408101825282546001600160a01b0390811682526001840154166020820152600283015491810191909152600382015460608201526004808301546080830152600583015460a0830152600683015460c0830152600783015460ff908116151560e08401526008840154610100840152600c840154610120840152600d840154610140840152600e840154610160840152600f84015461018084015260108401546101a084015260118401546101c084015260128401546101e08401526013840154811615156102008401526015840154939450600093610220840192911690811115610d0c57610d0c613719565b905290506000601583015460ff166004811115610d2b57610d2b613719565b148015610d3c575081600501544210155b15610d615760036102208201526007546005830154610d5b9190613b23565b60c08201525b9392505050565b610d7061254a565b80600003610dc05760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964207375706572766973696f6e206c6f636b2074696d650000006044820152606401610aab565b60078190556040518181527fefcc909882666285a1fdd8eaffaa6f85a24d42dbc2f144b90104edb140f0e95590602001610a2a565b6002546001600160a01b03163314610e1f5760405162461bcd60e51b8152600401610aab90613b3b565b600454811115610e625760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610aab565b8060046000828254610e749190613b62565b90915550506040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610eaf573d6000803e3d6000fd5b505050565b600080610ec0846126d4565b90506000610ed16009830185612846565b93505050505b92915050565b6003546001600160a01b03163314610f255760405162461bcd60e51b815260206004820152600b60248201526a37b7363c903a3930b232b960a91b6044820152606401610aab565b610f2d61267b565b6000610f38876126d4565b905080600501544210610f775760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610aab565b6000601582015460ff166004811115610f9257610f92613719565b14610faf5760405162461bcd60e51b8152600401610aab90613aec565b60018101546001600160a01b03166000908152600d602052604090205460ff1661100b5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a5908185cdcd95d609a1b6044820152606401610aab565b6008810154600382015461101e9161286d565b8411156110635760405162461bcd60e51b8152602060048201526013602482015272696e76616c696420747261646520707269636560681b6044820152606401610aab565b60018101546040516331a9108f60e11b81526004810187905230916001600160a01b031690636352211e90602401602060405180830381865afa1580156110ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d29190613b79565b6001600160a01b0316036111215760405162461bcd60e51b815260206004820152601660248201527568617665206f776e6564204e465420616c726561647960501b6044820152606401610aab565b6000868152600960205260409020546001600160a01b03168061117e5760405162461bcd60e51b8152602060048201526015602482015274696e76616c69642070726f7879206164647265737360581b6044820152606401610aab565b6000878152600a602052604090205460ff166111d35760405162461bcd60e51b8152602060048201526014602482015273696e76616c69642070726f78792073746174757360601b6044820152606401610aab565b6040805160608101825260018401546001600160a01b039081168252602082018990528183018890529151632238617960e21b815290918316906388e185e49088906112279085908a908a90600401613b96565b6000604051808303818588803b15801561124057600080fd5b505af193505050508015611252575060015b611295573d808015611280576040519150601f19603f3d011682016040523d82523d6000602084013e611285565b606091505b5061128f81612879565b5061143f565b80516040516331a9108f60e11b81526004810189905230916001600160a01b031690636352211e90602401602060405180830381865afa1580156112dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113019190613b79565b6001600160a01b0316146113465760405162461bcd60e51b815260206004820152600c60248201526b191bdb9d081bdddb8813919560a21b6044820152606401610aab565b60158301805460ff191660011790556007546113629042613b23565b6006840155600c8301889055600d8301879055600e83018690556113868984612885565b600e54600f546010546040516305d3b1d360e41b81526004810192909252600160a01b830467ffffffffffffffff1660248301526003604483015263ffffffff166064820152600160848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af1158015611408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142c9190613be9565b60009081526011602052604090208a9055505b50505061144b60018055565b505050505050565b6000806000611461846126d4565b600781015490915060ff161561147d5750600093849350915050565b8060060154421015806114c457506000601582015460ff1660048111156114a6576114a6613719565b1480156114c4575060075481600501546114c09190613b23565b4210155b156115355760006001601583015460ff1660048111156114e6576114e6613719565b148061150a57506002601583015460ff16600481111561150857611508613719565b145b801561151b5750601382015460ff16155b9050600061152883612adf565b9196919550909350505050565b50600093849350915050565b61154961267b565b6000611554826126d4565b600781015490915060ff161561157c5760405162461bcd60e51b8152600401610aab90613c02565b6115868282612bc2565b6003601582015460ff1660048111156115a1576115a1613719565b14806115c557506004601582015460ff1660048111156115c3576115c3613719565b145b6115e15760405162461bcd60e51b8152600401610aab90613aec565b33600090815260148201602052604090205460ff161561163c5760405162461bcd60e51b8152602060048201526016602482015275686176652077697468647261776e20616c726561647960501b6044820152606401610aab565b60008061164c6009840133612846565b91509150816116925760405162461bcd60e51b81526020600482015260126024820152711a5cc81b9bdd081c185c9d1a58da5c185b9d60721b6044820152606401610aab565b60006116ab846004015483612c3a90919063ffffffff16565b9093509050826116cd5760405162461bcd60e51b8152600401610aab90613c32565b336000818152601486016020526040808220805460ff191660011790555183156108fc0291849190818181858888f19350505050158015611712573d6000803e3d6000fd5b5060408051868152336020820152908101839052606081018290527f1c84cc0f96161bdafea718a9094dd21c21d1fb2f9ca2ebb9bd4e39918efbaace9060800160405180910390a15050505061176760018055565b50565b61177261254a565b8015801590611782575060085481105b6117c15760405162461bcd60e51b815260206004820152601060248201526f1a5b9d985b1a59081c1c9bde1e481a5960821b6044820152606401610aab565b6000818152600a602052604090205460ff166118145760405162461bcd60e51b8152602060048201526012602482015271756e726567697374656420616c726561647960701b6044820152606401610aab565b6000818152600a60209081526040808320805460ff19169055600982528083205481516001600160a01b0390911681529182018490528101919091527f4e435dde759dcf9c36050c45daa530f84ca2c3ab65c25980d826c0df56e5631090606001610a2a565b61188261254a565b61188c6000612c83565b565b61189661254a565b600e8054600f949094556010805463ffffffff90941663ffffffff199094169390931790925567ffffffffffffffff16600160a01b026001600160e01b03199092166001600160a01b0390931692909217179055565b60008060008060006118fd876126d4565b905060006002601583015460ff16600481111561191c5761191c613719565b0361194157866001600160a01b031661193483612cd3565b6001600160a01b03161490505b60006119506009840189612846565b9150600090506002601585015460ff16600481111561197157611971613719565b0361198d57601084015461198690839061286d565b90506119c1565b6002601585015460ff1660048111156119a8576119a8613719565b11156119c15760048401546119be90839061286d565b90505b60158401546001600160a01b038a166000908152601490950160205260409094205460ff948516985092965094505016905092959194509250565b6002546001600160a01b03163314611a265760405162461bcd60e51b8152600401610aab90613b3b565b60005b8251811015610eaf57611a55838281518110611a4757611a47613c57565b602002602001015183612d85565b80611a5f81613ad3565b915050611a29565b611a6f61254a565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b611a9961267b565b6000611aa4826126d4565b90506002601582015460ff166004811115611ac157611ac1613719565b14611ade5760405162461bcd60e51b8152600401610aab90613aec565b600781015460ff1615611b035760405162461bcd60e51b8152600401610aab90613c02565b33600090815260148201602052604090205460ff1615611b655760405162461bcd60e51b815260206004820152601a60248201527f6861766520676f7474656e206368616e676520616c72656164790000000000006044820152606401610aab565b611b6f8282612feb565b5061176760018055565b611b8161254a565b6001600160a01b0381166000818152600d60209081526040808320805460ff191690558051938452908301919091527ff419c416c0533e46364754aa7bdb0c5adbfce030a8424e1f348ce2cdc6eb89d79101610a2a565b611be061254a565b612710811015611c235760405162461bcd60e51b815260206004820152600e60248201526d34b73b30b634b2103330b1ba37b960911b6044820152606401610aab565b600655565b611c3061267b565b60005b81811015610bdf576000611c5e848484818110611c5257611c52613c57565b905060200201356126d4565b90506002601582015460ff166004811115611c7b57611c7b613719565b14611c985760405162461bcd60e51b8152600401610aab90613aec565b600781015460ff1615611cbd5760405162461bcd60e51b8152600401610aab90613c02565b33600090815260148201602052604090205460ff1615611d1f5760405162461bcd60e51b815260206004820152601a60248201527f6861766520676f7474656e206368616e676520616c72656164790000000000006044820152606401610aab565b611d41848484818110611d3457611d34613c57565b9050602002013582612feb565b5080611d4c81613ad3565b915050611c33565b611d5c61254a565b6000611d67826126d4565b90506000601582015460ff166004811115611d8457611d84613719565b14611da15760405162461bcd60e51b8152600401610aab90613aec565b60158101805460ff19166004179055600754611dbd9042613b23565b6006820155604051600080516020613d2683398151915290611de3908490600490613c6d565b60405180910390a15050565b611df761254a565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b03163314611e435760405162461bcd60e51b8152600401610aab90613b3b565b610abe8282612d85565b600080600080611e5c856126d4565b90506002601582015460ff166004811115611e7957611e79613719565b14611e93576015015460ff16925060009150819050611eb0565b6000611e9e82612cd3565b60109092015460029550919350909150505b9193909250565b611ebf61267b565b6000611eca826126d4565b600781015490915060ff1615611ef25760405162461bcd60e51b8152600401610aab90613c02565b6002601582015460ff166004811115611f0d57611f0d613719565b14611f2a5760405162461bcd60e51b8152600401610aab90613aec565b6000611f3582612cd3565b9050336001600160a01b03821614611f7f5760405162461bcd60e51b815260206004820152600d60248201526c34b9903737ba103bb4b73732b960991b6044820152606401610aab565b601382015460ff166120695760138201805460ff19166001908117909155820154600d8301546040516323b872dd60e01b81523060048201526001600160a01b03848116602483015260448201929092529116906323b872dd90606401600060405180830381600087803b158015611ff657600080fd5b505af115801561200a573d6000803e3d6000fd5b505050506001820154600d830154604080518681526001600160a01b0380861660208301529093169083015260608201527fb7e63d4c039ba02964e5322431009fa0a6402ce22c5ab01aa1818b17658da3619060800160405180910390a15b6001600160a01b038116600090815260148301602052604090205460ff1661218457600061209a6009840183612846565b60108501549092506000915081906120b3908490612c3a565b91509150816120d45760405162461bcd60e51b8152600401610aab90613c32565b6001600160a01b03841660009081526014860160205260409020805460ff191660011790558015612137576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015612135573d6000803e3d6000fd5b505b604080518781526001600160a01b03861660208201529081018290527fec5ebc1ec12ff76642d357b39d3e497c36fcab15f64f8a3ec71341b62e7ad5f49060600160405180910390a15050505b505061176760018055565b61219761254a565b6001600160a01b0381166121fc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aab565b61176781612c83565b60055460ff166122465760405162461bcd60e51b815260206004820152600c60248201526b6f6e6c79206f70656e696e6760a01b6044820152606401610aab565b61224e61267b565b6001600160a01b0384166122945760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a5908185cdcd95d609a1b6044820152606401610aab565b6001600160a01b0384166000908152600d602052604090205460ff166122f15760405162461bcd60e51b8152602060048201526012602482015271185cdcd95d081d5b9c9959da5cdd195c995960721b6044820152606401610aab565b826000036123375760405162461bcd60e51b8152602060048201526013602482015272696e76616c696420736861726520707269636560681b6044820152606401610aab565b8142106123865760405162461bcd60e51b815260206004820152601760248201527f696e76616c69642065787069726174696f6e2074696d650000000000000000006044820152606401610aab565b806000036123cb5760405162461bcd60e51b8152602060048201526012602482015271696e76616c6964206275792073686172657360701b6044820152606401610aab565b600b546000908152600c602052604081208054336001600160a01b03199182161782556006805460028401556001830180549092166001600160a01b0389161790915560038201869055600582018590556000198183015560158201805460ff19169055549091908190612440908790612c3a565b91509150816124845760405162461bcd60e51b815260206004820152601060248201526f1d5a5b9d081d1c9e535d5b0819985a5b60821b6044820152606401610aab565b6124908161271061310a565b60048401819055600b54604080519182526001600160a01b038a1660208301528101889052606081018790529091507f3affe688992d11cc7dd9fbe2a0c7db5de1c380fc8343d0578cb90eceb3e76aaf9060800160405180910390a1600080516020613d26833981519152600b54600060405161250e929190613c6d565b60405180910390a1612523600b54848661273b565b600b805490600061253383613ad3565b919050555050505061254460018055565b50505050565b6000546001600160a01b0316331461188c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aab565b600082815260116020526040812054908190036125f95760405162461bcd60e51b81526020600482015260136024820152721a5b9d985b1a590818dc9bddd9199d5b991259606a1b6044820152606401610aab565b6000612604826126d4565b90508260008151811061261957612619613c57565b60200260200101518160120181905550600754426126379190613b23565b600682015560158101805460ff19166002908117909155604051600080516020613d268339815191529161266d91859190613c6d565b60405180910390a150505050565b6002600154036126cd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610aab565b6002600155565b600080821180156126e65750600b5482105b6127295760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a590818dc9bddd9199d5b99081a5960621b6044820152606401610aab565b506000908152600c6020526040902090565b600882015460009061274d9083613116565b60088501559050806127715760405162461bcd60e51b8152600401610aab90613c81565b60048301546000906127839084612c3a565b9092509050816127a55760405162461bcd60e51b8152600401610aab90613c81565b6127b0600082613131565b60006127bf6009860133612846565b91506127cd90508185613116565b9093509050826127ef5760405162461bcd60e51b8152600401610aab90613c81565b6127fd60098601338361323e565b50604080518781523360208201529081018590527f66f5cd880edf48cdde6c966e5da0784fcc4c5e85572b8b3b62c4357798d447d79060600160405180910390a1505050505050565b600080808061285e866001600160a01b03871661325c565b909450925050505b9250929050565b6000610d618284613cab565b60208101815181018082fd5b6000806128a3836003015484600e015461329690919063ffffffff16565b91509150816128e25760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e54dd588819985a5b60aa1b6044820152606401610aab565b826003015483600e01546128f69190613ce0565b15612909578061290581613ad3565b9150505b600061292984600401548386600801546129239190613b62565b90612c3a565b90935090508261294b5760405162461bcd60e51b8152600401610aab90613c32565b600061296485600801548361329690919063ffffffff16565b9094509050836129a45760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e511a5d8819985a5b60aa1b6044820152606401610aab565b60006129c186600401548760080154612c3a90919063ffffffff16565b809250819650505060006129fa6129f388600e01546129ed8a600801548761286d90919063ffffffff16565b906132c9565b83906132d5565b909650905085612a3a5760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e54dd588819985a5b60aa1b6044820152606401610aab565b600454612a479082613116565b600455955085612a875760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e5059190819985a5b60aa1b6044820152606401610aab565b600f8701859055601087018390556011870181905560408051898152602081018390527f7893d8ce48cf0384f5420e94c30695b9be1abb188c2024a6eb485031c522da72910160405180910390a15050505050505050565b6000806000806000612af3866009016132f7565b905060005b81811015612b5357612b0d6009880182613302565b6001600160a01b038216600090815260148a016020526040902054919550935060ff16612b4157612b3e8386613b23565b94505b80612b4b81613ad3565b915050612af8565b506001601587015460ff166004811115612b6f57612b6f613719565b1480612b9357506002601587015460ff166004811115612b9157612b91613719565b145b15612bb257838660100154612ba89190613cab565b9695505050505050565b838660040154612ba89190613cab565b6000601582015460ff166004811115612bdd57612bdd613719565b148015612bee575080600501544210155b15610abe5760158101805460ff191660031790556007546005820154612c149190613b23565b6006820155604051600080516020613d2683398151915290611de3908490600390613c6d565b60008083600003612c515750600190506000612866565b83830283858281612c6457612c64613cca565b0414612c77576000809250925050612866565b60019590945092505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008084600801548560120154612ced9190613ce0565b612cf8906001613b23565b90506000612d08866009016132f7565b905060005b612d18600183613b62565b811015612d6157612d2c6009880182613302565b9095509350838311612d4357509295945050505050565b612d4d8484613b62565b925080612d5981613ad3565b915050612d0d565b50612d7a612d70600183613b62565b6009880190613302565b509695505050505050565b6000612d90836126d4565b600781015490915060ff1615612db85760405162461bcd60e51b8152600401610aab90613c02565b612dc28382612bc2565b8060060154421015612e165760405162461bcd60e51b815260206004820152601860248201527f6e6f7420796574207375706572766973696f6e2074696d6500000000000000006044820152606401610aab565b60078101805460ff19166001908117909155600090601583015460ff166004811115612e4457612e44613719565b1480612e6857506002601583015460ff166004811115612e6657612e66613719565b145b8015612e795750601382015460ff16155b90508015612f4f576001820154600d8301546040516323b872dd60e01b81523060048201526001600160a01b03868116602483015260448201929092529116906323b872dd90606401600060405180830381600087803b158015612edc57600080fd5b505af1158015612ef0573d6000803e3d6000fd5b505050506001820154600d830154604080518781526001600160a01b0380881660208301529093169083015260608201527f13ddf09152b2b598ff3c9b764e4098223f512603bbbb0952f0a145d7b9857f3a9060800160405180910390a15b6000612f5a83612adf565b90508015612fe4576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015612f98573d6000803e3d6000fd5b50604080518681526001600160a01b03861660208201529081018290527fbb3160732946e5551ad7239b7d16f03020ae78497b192478d288792fa8544ad9906060015b60405180910390a15b5050505050565b600080612ffb6009840133612846565b91509150816130415760405162461bcd60e51b81526020600482015260126024820152711a5cc81b9bdd081c185c9d1a58da5c185b9d60721b6044820152606401610aab565b600061305a846010015483612c3a90919063ffffffff16565b90935090508261307c5760405162461bcd60e51b8152600401610aab90613c32565b3360009081526014850160205260409020805460ff1916600117905580156130cd57604051339082156108fc029083906000818181858888f193505050501580156130cb573d6000803e3d6000fd5b505b604080518681523360208201529081018290527fec5ebc1ec12ff76642d357b39d3e497c36fcab15f64f8a3ec71341b62e7ad5f490606001612fdb565b6000610d618284613cf4565b60008083830184811015612c77576000809250925050612866565b8015610abe576001600160a01b0382166131825780341015610abe5760405162461bcd60e51b815260206004820152600a6024820152690dcdee840cadcdeeaced60b31b6044820152606401610aab565b6040516323b872dd60e01b8152336004820152306024820152604481018290526001600160a01b038316906323b872dd906064016020604051808303816000875af11580156131d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f99190613d08565b610abe5760405162461bcd60e51b81526020600482015260166024820152751d1c985b9cd9995c881a5b881b5bdb995e4819985a5b60521b6044820152606401610aab565b6000613254846001600160a01b03851684613311565b949350505050565b600081815260028301602052604081205481908061328b5761327e858561332e565b9250600091506128669050565b600192509050612866565b600080826000036132ac57506000905080612866565b60018385816132bd576132bd613cca565b04915091509250929050565b6000610d618284613b23565b600080838311156132eb57506000905080612866565b50600193919092039150565b6000610ed78261333a565b600080808061285e8686613345565b600082815260028401602052604081208290556132548484613370565b6000610d61838361337c565b6000610ed782613394565b60008080613353858561339e565b600081815260029690960160205260409095205494959350505050565b6000610d6183836133aa565b60008181526001830160205260408120541515610d61565b6000610ed7825490565b6000610d6183836133f9565b60008181526001830160205260408120546133f157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ed7565b506000610ed7565b600082600001828154811061341057613410613c57565b9060005260206000200154905092915050565b60405180610240016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600060048111156134cf576134cf613719565b905290565b6001600160a01b038116811461176757600080fd5b6000602082840312156134fb57600080fd5b8135610d61816134d4565b60008083601f84011261351857600080fd5b50813567ffffffffffffffff81111561353057600080fd5b60208301915083602082850101111561286657600080fd5b60008060008060006080868803121561356057600080fd5b853561356b816134d4565b9450602086013561357b816134d4565b935060408601359250606086013567ffffffffffffffff81111561359e57600080fd5b6135aa88828901613506565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126135e257600080fd5b8135602067ffffffffffffffff808311156135ff576135ff6135bb565b8260051b604051601f19603f83011681018181108482111715613624576136246135bb565b60405293845285810183019383810192508785111561364257600080fd5b83870191505b8482101561366157813583529183019190830190613648565b979650505050505050565b6000806040838503121561367f57600080fd5b82359150602083013567ffffffffffffffff81111561369d57600080fd5b6136a9858286016135d1565b9150509250929050565b600080604083850312156136c657600080fd5b50508035926020909101359150565b801515811461176757600080fd5b6000602082840312156136f557600080fd5b8135610d61816136d5565b60006020828403121561371257600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061374d57634e487b7160e01b600052602160045260246000fd5b9052565b81516001600160a01b031681526102408101602083015161377d60208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e08301516137c360e084018215159052565b50610100838101519083015261012080840151908301526101408084015190830152610160808401519083015261018080840151908301526101a080840151908301526101c080840151908301526101e08084015190830152610200808401511515908301526102208084015161383c8285018261372f565b505092915050565b6000806040838503121561385757600080fd5b8235613862816134d4565b946020939093013593505050565b6000806040838503121561388357600080fd5b823591506020830135613895816134d4565b809150509250929050565b60008060008060008060a087890312156138b957600080fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff8111156138ec57600080fd5b6138f889828a01613506565b979a9699509497509295939492505050565b6000806000806080858703121561392057600080fd5b843561392b816134d4565b935060208501359250604085013563ffffffff8116811461394b57600080fd5b9150606085013567ffffffffffffffff8116811461396857600080fd5b939692955090935050565b60808101613981828761372f565b931515602082015260408101929092521515606090910152919050565b600080604083850312156139b157600080fd5b823567ffffffffffffffff8111156139c857600080fd5b6139d4858286016135d1565b9250506020830135613895816134d4565b600080602083850312156139f857600080fd5b823567ffffffffffffffff80821115613a1057600080fd5b818501915085601f830112613a2457600080fd5b813581811115613a3357600080fd5b8660208260051b8501011115613a4857600080fd5b60209290920196919550909350505050565b60608101613a68828661372f565b6001600160a01b0393909316602082015260400152919050565b60008060008060808587031215613a9857600080fd5b8435613aa3816134d4565b966020860135965060408601359560600135945092505050565b634e487b7160e01b600052601160045260246000fd5b600060018201613ae557613ae5613abd565b5060010190565b60208082526018908201527f696e76616c69642063726f776466756e64207374617475730000000000000000604082015260600190565b60008219821115613b3657613b36613abd565b500190565b6020808252600d908201526c6f6e6c7920747265617375727960981b604082015260600190565b600082821015613b7457613b74613abd565b500390565b600060208284031215613b8b57600080fd5b8151610d61816134d4565b60018060a01b038451168152602084015160208201526040840151604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f1916010192915050565b600060208284031215613bfb57600080fd5b5051919050565b60208082526016908201527568617665206d6f76656420746f20747265617375727960501b604082015260600190565b6020808252600b908201526a1d1c9e535d5b0819985a5b60aa1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b82815260408101610d61602083018461372f565b60208082526010908201526f696e76616c6964207175616e7469747960801b604082015260600190565b6000816000190483118215151615613cc557613cc5613abd565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613cef57613cef613cca565b500690565b600082613d0357613d03613cca565b500490565b600060208284031215613d1a57600080fd5b8151610d61816136d556fe365a3d0a71be5f440c8224437355d5bd81a703759bf906e441902272bfbafcb3a26469706673582212204c774e89a196b0ab7acddaf9d634f6197fc47edc6b65e68de3b190f5e0d2607964736f6c634300080d0033000000000000000000000000435bf54516dc869dc440042566972122e765147d0000000000000000000000003b4331d3c0e707ab067bfcf290cfa8e068b7e5be000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990900000000000000000000000000000000000000000000000000000000000002288af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000186a0
Deployed Bytecode
0x6080604052600436106102885760003560e01c80637181160c1161015a578063b71309f8116100c1578063e9fc660d1161007a578063e9fc660d1461086c578063f11b81881461088c578063f2fde38b146108bc578063f628f673146108dc578063fcfff16f146108ef578063ff00148a1461090957600080fd5b8063b71309f81461078b578063beae6e6c146107ab578063cb38e238146107dd578063cb7ef3e5146107fd578063dd07694a1461081d578063e56b9dce1461083d57600080fd5b80639fc5fb2c116101135780639fc5fb2c14610695578063a3e56fa8146106b5578063abd90f85146106d5578063af5cd2421461070b578063b0dd7c521461074b578063b6f50ec01461076b57600080fd5b80637181160c146105d1578063731fb408146105f15780638a0d20ef146106215780638da5cb5b14610641578063910764c91461065f578063985b4dd41461067557600080fd5b8063425c9fa2116101fe57806359be45bc116101b757806359be45bc146105055780635a758cd0146105255780635b6b431d1461055c5780635f13e0c41461057c57806361d027b31461059c578063715018a6146105bc57600080fd5b8063425c9fa21461043557806342a59d27146104625780634418a5051461048f578063447d53be146104af5780634d69c6c6146104cf57806354f703f8146104ef57600080fd5b80631fe543e3116102505780631fe543e31461037557806321f224201461039557806329484706146103a85780632f337fec146103c857806332615640146103de5780633e9491a21461041f57600080fd5b8063041d443e1461028d57806309c50a44146102b6578063150b7a02146102d85780631758078b1461031d5780631d034b2e14610355575b600080fd5b34801561029957600080fd5b506102a3600f5481565b6040519081526020015b60405180910390f35b3480156102c257600080fd5b506102d66102d13660046134e9565b61091f565b005b3480156102e457600080fd5b506103046102f3366004613548565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016102ad565b34801561032957600080fd5b5060035461033d906001600160a01b031681565b6040516001600160a01b0390911681526020016102ad565b34801561036157600080fd5b506102d66103703660046134e9565b6109cb565b34801561038157600080fd5b506102d661039036600461366c565b610a35565b6102d66103a33660046136b3565b610ac2565b3480156103b457600080fd5b506102d66103c33660046136e3565b610be9565b3480156103d457600080fd5b506102a3600b5481565b3480156103ea57600080fd5b50600e5461040690600160a01b900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102ad565b34801561042b57600080fd5b506102a360045481565b34801561044157600080fd5b506102a3610450366004613700565b60116020526000908152604090205481565b34801561046e57600080fd5b5061048261047d366004613700565b610c04565b6040516102ad9190613751565b34801561049b57600080fd5b506102d66104aa366004613700565b610d68565b3480156104bb57600080fd5b506102d66104ca366004613844565b610df5565b3480156104db57600080fd5b506102a36104ea366004613870565b610eb4565b3480156104fb57600080fd5b506102a360065481565b34801561051157600080fd5b506102d66105203660046138a0565b610edd565b34801561053157600080fd5b50610545610540366004613700565b611453565b6040805192151583526020830191909152016102ad565b34801561056857600080fd5b506102d6610577366004613700565b611541565b34801561058857600080fd5b506102d6610597366004613700565b61176a565b3480156105a857600080fd5b5060025461033d906001600160a01b031681565b3480156105c857600080fd5b506102d661187a565b3480156105dd57600080fd5b506102d66105ec36600461390a565b61188e565b3480156105fd57600080fd5b5061061161060c366004613870565b6118ec565b6040516102ad9493929190613973565b34801561062d57600080fd5b506102d661063c36600461399e565b6119fc565b34801561064d57600080fd5b506000546001600160a01b031661033d565b34801561066b57600080fd5b506102a360075481565b34801561068157600080fd5b506102d66106903660046134e9565b611a67565b3480156106a157600080fd5b506102d66106b0366004613700565b611a91565b3480156106c157600080fd5b50600e5461033d906001600160a01b031681565b3480156106e157600080fd5b5061033d6106f0366004613700565b6009602052600090815260409020546001600160a01b031681565b34801561071757600080fd5b5061073b610726366004613700565b600a6020526000908152604090205460ff1681565b60405190151581526020016102ad565b34801561075757600080fd5b506102d66107663660046134e9565b611b79565b34801561077757600080fd5b506102d6610786366004613700565b611bd8565b34801561079757600080fd5b506102d66107a63660046139e5565b611c28565b3480156107b757600080fd5b506010546107c89063ffffffff1681565b60405163ffffffff90911681526020016102ad565b3480156107e957600080fd5b506102d66107f8366004613700565b611d54565b34801561080957600080fd5b506102d66108183660046134e9565b611def565b34801561082957600080fd5b506102d6610838366004613870565b611e19565b34801561084957600080fd5b5061085d610858366004613700565b611e4d565b6040516102ad93929190613a5a565b34801561087857600080fd5b506102d6610887366004613700565b611eb7565b34801561089857600080fd5b5061073b6108a73660046134e9565b600d6020526000908152604090205460ff1681565b3480156108c857600080fd5b506102d66108d73660046134e9565b61218f565b6102d66108ea366004613a82565b612205565b3480156108fb57600080fd5b5060055461073b9060ff1681565b34801561091557600080fd5b506102a360085481565b61092761254a565b60088054600090815260096020908152604080832080546001600160a01b0319166001600160a01b03871690811790915584548452600a835292819020805460ff1916600190811790915593548151938452918301919091528101919091527f4e435dde759dcf9c36050c45daa530f84ca2c3ab65c25980d826c0df56e563109060600160405180910390a1600880549060006109c383613ad3565b919050555050565b6109d361254a565b6001600160a01b0381166000818152600d6020908152604091829020805460ff191660019081179091558251938452908301527ff419c416c0533e46364754aa7bdb0c5adbfce030a8424e1f348ce2cdc6eb89d791015b60405180910390a150565b336001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699091614610ab45760405163073e64fd60e21b81523360048201526001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699091660248201526044015b60405180910390fd5b610abe82826125a4565b5050565b60055460ff16610b035760405162461bcd60e51b815260206004820152600c60248201526b6f6e6c79206f70656e696e6760a01b6044820152606401610aab565b610b0b61267b565b6000610b16836126d4565b905080600501544210610b555760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610aab565b6000601582015460ff166004811115610b7057610b70613719565b14610b8d5760405162461bcd60e51b8152600401610aab90613aec565b81600003610bd45760405162461bcd60e51b8152602060048201526014602482015273696e76616c696420627579207175616e7469747960601b6044820152606401610aab565b610bdf83828461273b565b50610abe60018055565b610bf161254a565b6005805460ff1916911515919091179055565b610c0c613423565b6000610c17836126d4565b604080516102408101825282546001600160a01b0390811682526001840154166020820152600283015491810191909152600382015460608201526004808301546080830152600583015460a0830152600683015460c0830152600783015460ff908116151560e08401526008840154610100840152600c840154610120840152600d840154610140840152600e840154610160840152600f84015461018084015260108401546101a084015260118401546101c084015260128401546101e08401526013840154811615156102008401526015840154939450600093610220840192911690811115610d0c57610d0c613719565b905290506000601583015460ff166004811115610d2b57610d2b613719565b148015610d3c575081600501544210155b15610d615760036102208201526007546005830154610d5b9190613b23565b60c08201525b9392505050565b610d7061254a565b80600003610dc05760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964207375706572766973696f6e206c6f636b2074696d650000006044820152606401610aab565b60078190556040518181527fefcc909882666285a1fdd8eaffaa6f85a24d42dbc2f144b90104edb140f0e95590602001610a2a565b6002546001600160a01b03163314610e1f5760405162461bcd60e51b8152600401610aab90613b3b565b600454811115610e625760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610aab565b8060046000828254610e749190613b62565b90915550506040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610eaf573d6000803e3d6000fd5b505050565b600080610ec0846126d4565b90506000610ed16009830185612846565b93505050505b92915050565b6003546001600160a01b03163314610f255760405162461bcd60e51b815260206004820152600b60248201526a37b7363c903a3930b232b960a91b6044820152606401610aab565b610f2d61267b565b6000610f38876126d4565b905080600501544210610f775760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610aab565b6000601582015460ff166004811115610f9257610f92613719565b14610faf5760405162461bcd60e51b8152600401610aab90613aec565b60018101546001600160a01b03166000908152600d602052604090205460ff1661100b5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a5908185cdcd95d609a1b6044820152606401610aab565b6008810154600382015461101e9161286d565b8411156110635760405162461bcd60e51b8152602060048201526013602482015272696e76616c696420747261646520707269636560681b6044820152606401610aab565b60018101546040516331a9108f60e11b81526004810187905230916001600160a01b031690636352211e90602401602060405180830381865afa1580156110ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d29190613b79565b6001600160a01b0316036111215760405162461bcd60e51b815260206004820152601660248201527568617665206f776e6564204e465420616c726561647960501b6044820152606401610aab565b6000868152600960205260409020546001600160a01b03168061117e5760405162461bcd60e51b8152602060048201526015602482015274696e76616c69642070726f7879206164647265737360581b6044820152606401610aab565b6000878152600a602052604090205460ff166111d35760405162461bcd60e51b8152602060048201526014602482015273696e76616c69642070726f78792073746174757360601b6044820152606401610aab565b6040805160608101825260018401546001600160a01b039081168252602082018990528183018890529151632238617960e21b815290918316906388e185e49088906112279085908a908a90600401613b96565b6000604051808303818588803b15801561124057600080fd5b505af193505050508015611252575060015b611295573d808015611280576040519150601f19603f3d011682016040523d82523d6000602084013e611285565b606091505b5061128f81612879565b5061143f565b80516040516331a9108f60e11b81526004810189905230916001600160a01b031690636352211e90602401602060405180830381865afa1580156112dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113019190613b79565b6001600160a01b0316146113465760405162461bcd60e51b815260206004820152600c60248201526b191bdb9d081bdddb8813919560a21b6044820152606401610aab565b60158301805460ff191660011790556007546113629042613b23565b6006840155600c8301889055600d8301879055600e83018690556113868984612885565b600e54600f546010546040516305d3b1d360e41b81526004810192909252600160a01b830467ffffffffffffffff1660248301526003604483015263ffffffff166064820152600160848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af1158015611408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142c9190613be9565b60009081526011602052604090208a9055505b50505061144b60018055565b505050505050565b6000806000611461846126d4565b600781015490915060ff161561147d5750600093849350915050565b8060060154421015806114c457506000601582015460ff1660048111156114a6576114a6613719565b1480156114c4575060075481600501546114c09190613b23565b4210155b156115355760006001601583015460ff1660048111156114e6576114e6613719565b148061150a57506002601583015460ff16600481111561150857611508613719565b145b801561151b5750601382015460ff16155b9050600061152883612adf565b9196919550909350505050565b50600093849350915050565b61154961267b565b6000611554826126d4565b600781015490915060ff161561157c5760405162461bcd60e51b8152600401610aab90613c02565b6115868282612bc2565b6003601582015460ff1660048111156115a1576115a1613719565b14806115c557506004601582015460ff1660048111156115c3576115c3613719565b145b6115e15760405162461bcd60e51b8152600401610aab90613aec565b33600090815260148201602052604090205460ff161561163c5760405162461bcd60e51b8152602060048201526016602482015275686176652077697468647261776e20616c726561647960501b6044820152606401610aab565b60008061164c6009840133612846565b91509150816116925760405162461bcd60e51b81526020600482015260126024820152711a5cc81b9bdd081c185c9d1a58da5c185b9d60721b6044820152606401610aab565b60006116ab846004015483612c3a90919063ffffffff16565b9093509050826116cd5760405162461bcd60e51b8152600401610aab90613c32565b336000818152601486016020526040808220805460ff191660011790555183156108fc0291849190818181858888f19350505050158015611712573d6000803e3d6000fd5b5060408051868152336020820152908101839052606081018290527f1c84cc0f96161bdafea718a9094dd21c21d1fb2f9ca2ebb9bd4e39918efbaace9060800160405180910390a15050505061176760018055565b50565b61177261254a565b8015801590611782575060085481105b6117c15760405162461bcd60e51b815260206004820152601060248201526f1a5b9d985b1a59081c1c9bde1e481a5960821b6044820152606401610aab565b6000818152600a602052604090205460ff166118145760405162461bcd60e51b8152602060048201526012602482015271756e726567697374656420616c726561647960701b6044820152606401610aab565b6000818152600a60209081526040808320805460ff19169055600982528083205481516001600160a01b0390911681529182018490528101919091527f4e435dde759dcf9c36050c45daa530f84ca2c3ab65c25980d826c0df56e5631090606001610a2a565b61188261254a565b61188c6000612c83565b565b61189661254a565b600e8054600f949094556010805463ffffffff90941663ffffffff199094169390931790925567ffffffffffffffff16600160a01b026001600160e01b03199092166001600160a01b0390931692909217179055565b60008060008060006118fd876126d4565b905060006002601583015460ff16600481111561191c5761191c613719565b0361194157866001600160a01b031661193483612cd3565b6001600160a01b03161490505b60006119506009840189612846565b9150600090506002601585015460ff16600481111561197157611971613719565b0361198d57601084015461198690839061286d565b90506119c1565b6002601585015460ff1660048111156119a8576119a8613719565b11156119c15760048401546119be90839061286d565b90505b60158401546001600160a01b038a166000908152601490950160205260409094205460ff948516985092965094505016905092959194509250565b6002546001600160a01b03163314611a265760405162461bcd60e51b8152600401610aab90613b3b565b60005b8251811015610eaf57611a55838281518110611a4757611a47613c57565b602002602001015183612d85565b80611a5f81613ad3565b915050611a29565b611a6f61254a565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b611a9961267b565b6000611aa4826126d4565b90506002601582015460ff166004811115611ac157611ac1613719565b14611ade5760405162461bcd60e51b8152600401610aab90613aec565b600781015460ff1615611b035760405162461bcd60e51b8152600401610aab90613c02565b33600090815260148201602052604090205460ff1615611b655760405162461bcd60e51b815260206004820152601a60248201527f6861766520676f7474656e206368616e676520616c72656164790000000000006044820152606401610aab565b611b6f8282612feb565b5061176760018055565b611b8161254a565b6001600160a01b0381166000818152600d60209081526040808320805460ff191690558051938452908301919091527ff419c416c0533e46364754aa7bdb0c5adbfce030a8424e1f348ce2cdc6eb89d79101610a2a565b611be061254a565b612710811015611c235760405162461bcd60e51b815260206004820152600e60248201526d34b73b30b634b2103330b1ba37b960911b6044820152606401610aab565b600655565b611c3061267b565b60005b81811015610bdf576000611c5e848484818110611c5257611c52613c57565b905060200201356126d4565b90506002601582015460ff166004811115611c7b57611c7b613719565b14611c985760405162461bcd60e51b8152600401610aab90613aec565b600781015460ff1615611cbd5760405162461bcd60e51b8152600401610aab90613c02565b33600090815260148201602052604090205460ff1615611d1f5760405162461bcd60e51b815260206004820152601a60248201527f6861766520676f7474656e206368616e676520616c72656164790000000000006044820152606401610aab565b611d41848484818110611d3457611d34613c57565b9050602002013582612feb565b5080611d4c81613ad3565b915050611c33565b611d5c61254a565b6000611d67826126d4565b90506000601582015460ff166004811115611d8457611d84613719565b14611da15760405162461bcd60e51b8152600401610aab90613aec565b60158101805460ff19166004179055600754611dbd9042613b23565b6006820155604051600080516020613d2683398151915290611de3908490600490613c6d565b60405180910390a15050565b611df761254a565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b03163314611e435760405162461bcd60e51b8152600401610aab90613b3b565b610abe8282612d85565b600080600080611e5c856126d4565b90506002601582015460ff166004811115611e7957611e79613719565b14611e93576015015460ff16925060009150819050611eb0565b6000611e9e82612cd3565b60109092015460029550919350909150505b9193909250565b611ebf61267b565b6000611eca826126d4565b600781015490915060ff1615611ef25760405162461bcd60e51b8152600401610aab90613c02565b6002601582015460ff166004811115611f0d57611f0d613719565b14611f2a5760405162461bcd60e51b8152600401610aab90613aec565b6000611f3582612cd3565b9050336001600160a01b03821614611f7f5760405162461bcd60e51b815260206004820152600d60248201526c34b9903737ba103bb4b73732b960991b6044820152606401610aab565b601382015460ff166120695760138201805460ff19166001908117909155820154600d8301546040516323b872dd60e01b81523060048201526001600160a01b03848116602483015260448201929092529116906323b872dd90606401600060405180830381600087803b158015611ff657600080fd5b505af115801561200a573d6000803e3d6000fd5b505050506001820154600d830154604080518681526001600160a01b0380861660208301529093169083015260608201527fb7e63d4c039ba02964e5322431009fa0a6402ce22c5ab01aa1818b17658da3619060800160405180910390a15b6001600160a01b038116600090815260148301602052604090205460ff1661218457600061209a6009840183612846565b60108501549092506000915081906120b3908490612c3a565b91509150816120d45760405162461bcd60e51b8152600401610aab90613c32565b6001600160a01b03841660009081526014860160205260409020805460ff191660011790558015612137576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015612135573d6000803e3d6000fd5b505b604080518781526001600160a01b03861660208201529081018290527fec5ebc1ec12ff76642d357b39d3e497c36fcab15f64f8a3ec71341b62e7ad5f49060600160405180910390a15050505b505061176760018055565b61219761254a565b6001600160a01b0381166121fc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aab565b61176781612c83565b60055460ff166122465760405162461bcd60e51b815260206004820152600c60248201526b6f6e6c79206f70656e696e6760a01b6044820152606401610aab565b61224e61267b565b6001600160a01b0384166122945760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a5908185cdcd95d609a1b6044820152606401610aab565b6001600160a01b0384166000908152600d602052604090205460ff166122f15760405162461bcd60e51b8152602060048201526012602482015271185cdcd95d081d5b9c9959da5cdd195c995960721b6044820152606401610aab565b826000036123375760405162461bcd60e51b8152602060048201526013602482015272696e76616c696420736861726520707269636560681b6044820152606401610aab565b8142106123865760405162461bcd60e51b815260206004820152601760248201527f696e76616c69642065787069726174696f6e2074696d650000000000000000006044820152606401610aab565b806000036123cb5760405162461bcd60e51b8152602060048201526012602482015271696e76616c6964206275792073686172657360701b6044820152606401610aab565b600b546000908152600c602052604081208054336001600160a01b03199182161782556006805460028401556001830180549092166001600160a01b0389161790915560038201869055600582018590556000198183015560158201805460ff19169055549091908190612440908790612c3a565b91509150816124845760405162461bcd60e51b815260206004820152601060248201526f1d5a5b9d081d1c9e535d5b0819985a5b60821b6044820152606401610aab565b6124908161271061310a565b60048401819055600b54604080519182526001600160a01b038a1660208301528101889052606081018790529091507f3affe688992d11cc7dd9fbe2a0c7db5de1c380fc8343d0578cb90eceb3e76aaf9060800160405180910390a1600080516020613d26833981519152600b54600060405161250e929190613c6d565b60405180910390a1612523600b54848661273b565b600b805490600061253383613ad3565b919050555050505061254460018055565b50505050565b6000546001600160a01b0316331461188c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aab565b600082815260116020526040812054908190036125f95760405162461bcd60e51b81526020600482015260136024820152721a5b9d985b1a590818dc9bddd9199d5b991259606a1b6044820152606401610aab565b6000612604826126d4565b90508260008151811061261957612619613c57565b60200260200101518160120181905550600754426126379190613b23565b600682015560158101805460ff19166002908117909155604051600080516020613d268339815191529161266d91859190613c6d565b60405180910390a150505050565b6002600154036126cd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610aab565b6002600155565b600080821180156126e65750600b5482105b6127295760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a590818dc9bddd9199d5b99081a5960621b6044820152606401610aab565b506000908152600c6020526040902090565b600882015460009061274d9083613116565b60088501559050806127715760405162461bcd60e51b8152600401610aab90613c81565b60048301546000906127839084612c3a565b9092509050816127a55760405162461bcd60e51b8152600401610aab90613c81565b6127b0600082613131565b60006127bf6009860133612846565b91506127cd90508185613116565b9093509050826127ef5760405162461bcd60e51b8152600401610aab90613c81565b6127fd60098601338361323e565b50604080518781523360208201529081018590527f66f5cd880edf48cdde6c966e5da0784fcc4c5e85572b8b3b62c4357798d447d79060600160405180910390a1505050505050565b600080808061285e866001600160a01b03871661325c565b909450925050505b9250929050565b6000610d618284613cab565b60208101815181018082fd5b6000806128a3836003015484600e015461329690919063ffffffff16565b91509150816128e25760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e54dd588819985a5b60aa1b6044820152606401610aab565b826003015483600e01546128f69190613ce0565b15612909578061290581613ad3565b9150505b600061292984600401548386600801546129239190613b62565b90612c3a565b90935090508261294b5760405162461bcd60e51b8152600401610aab90613c32565b600061296485600801548361329690919063ffffffff16565b9094509050836129a45760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e511a5d8819985a5b60aa1b6044820152606401610aab565b60006129c186600401548760080154612c3a90919063ffffffff16565b809250819650505060006129fa6129f388600e01546129ed8a600801548761286d90919063ffffffff16565b906132c9565b83906132d5565b909650905085612a3a5760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e54dd588819985a5b60aa1b6044820152606401610aab565b600454612a479082613116565b600455955085612a875760405162461bcd60e51b815260206004820152600b60248201526a1d1c9e5059190819985a5b60aa1b6044820152606401610aab565b600f8701859055601087018390556011870181905560408051898152602081018390527f7893d8ce48cf0384f5420e94c30695b9be1abb188c2024a6eb485031c522da72910160405180910390a15050505050505050565b6000806000806000612af3866009016132f7565b905060005b81811015612b5357612b0d6009880182613302565b6001600160a01b038216600090815260148a016020526040902054919550935060ff16612b4157612b3e8386613b23565b94505b80612b4b81613ad3565b915050612af8565b506001601587015460ff166004811115612b6f57612b6f613719565b1480612b9357506002601587015460ff166004811115612b9157612b91613719565b145b15612bb257838660100154612ba89190613cab565b9695505050505050565b838660040154612ba89190613cab565b6000601582015460ff166004811115612bdd57612bdd613719565b148015612bee575080600501544210155b15610abe5760158101805460ff191660031790556007546005820154612c149190613b23565b6006820155604051600080516020613d2683398151915290611de3908490600390613c6d565b60008083600003612c515750600190506000612866565b83830283858281612c6457612c64613cca565b0414612c77576000809250925050612866565b60019590945092505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008084600801548560120154612ced9190613ce0565b612cf8906001613b23565b90506000612d08866009016132f7565b905060005b612d18600183613b62565b811015612d6157612d2c6009880182613302565b9095509350838311612d4357509295945050505050565b612d4d8484613b62565b925080612d5981613ad3565b915050612d0d565b50612d7a612d70600183613b62565b6009880190613302565b509695505050505050565b6000612d90836126d4565b600781015490915060ff1615612db85760405162461bcd60e51b8152600401610aab90613c02565b612dc28382612bc2565b8060060154421015612e165760405162461bcd60e51b815260206004820152601860248201527f6e6f7420796574207375706572766973696f6e2074696d6500000000000000006044820152606401610aab565b60078101805460ff19166001908117909155600090601583015460ff166004811115612e4457612e44613719565b1480612e6857506002601583015460ff166004811115612e6657612e66613719565b145b8015612e795750601382015460ff16155b90508015612f4f576001820154600d8301546040516323b872dd60e01b81523060048201526001600160a01b03868116602483015260448201929092529116906323b872dd90606401600060405180830381600087803b158015612edc57600080fd5b505af1158015612ef0573d6000803e3d6000fd5b505050506001820154600d830154604080518781526001600160a01b0380881660208301529093169083015260608201527f13ddf09152b2b598ff3c9b764e4098223f512603bbbb0952f0a145d7b9857f3a9060800160405180910390a15b6000612f5a83612adf565b90508015612fe4576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015612f98573d6000803e3d6000fd5b50604080518681526001600160a01b03861660208201529081018290527fbb3160732946e5551ad7239b7d16f03020ae78497b192478d288792fa8544ad9906060015b60405180910390a15b5050505050565b600080612ffb6009840133612846565b91509150816130415760405162461bcd60e51b81526020600482015260126024820152711a5cc81b9bdd081c185c9d1a58da5c185b9d60721b6044820152606401610aab565b600061305a846010015483612c3a90919063ffffffff16565b90935090508261307c5760405162461bcd60e51b8152600401610aab90613c32565b3360009081526014850160205260409020805460ff1916600117905580156130cd57604051339082156108fc029083906000818181858888f193505050501580156130cb573d6000803e3d6000fd5b505b604080518681523360208201529081018290527fec5ebc1ec12ff76642d357b39d3e497c36fcab15f64f8a3ec71341b62e7ad5f490606001612fdb565b6000610d618284613cf4565b60008083830184811015612c77576000809250925050612866565b8015610abe576001600160a01b0382166131825780341015610abe5760405162461bcd60e51b815260206004820152600a6024820152690dcdee840cadcdeeaced60b31b6044820152606401610aab565b6040516323b872dd60e01b8152336004820152306024820152604481018290526001600160a01b038316906323b872dd906064016020604051808303816000875af11580156131d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f99190613d08565b610abe5760405162461bcd60e51b81526020600482015260166024820152751d1c985b9cd9995c881a5b881b5bdb995e4819985a5b60521b6044820152606401610aab565b6000613254846001600160a01b03851684613311565b949350505050565b600081815260028301602052604081205481908061328b5761327e858561332e565b9250600091506128669050565b600192509050612866565b600080826000036132ac57506000905080612866565b60018385816132bd576132bd613cca565b04915091509250929050565b6000610d618284613b23565b600080838311156132eb57506000905080612866565b50600193919092039150565b6000610ed78261333a565b600080808061285e8686613345565b600082815260028401602052604081208290556132548484613370565b6000610d61838361337c565b6000610ed782613394565b60008080613353858561339e565b600081815260029690960160205260409095205494959350505050565b6000610d6183836133aa565b60008181526001830160205260408120541515610d61565b6000610ed7825490565b6000610d6183836133f9565b60008181526001830160205260408120546133f157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ed7565b506000610ed7565b600082600001828154811061341057613410613c57565b9060005260206000200154905092915050565b60405180610240016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600060048111156134cf576134cf613719565b905290565b6001600160a01b038116811461176757600080fd5b6000602082840312156134fb57600080fd5b8135610d61816134d4565b60008083601f84011261351857600080fd5b50813567ffffffffffffffff81111561353057600080fd5b60208301915083602082850101111561286657600080fd5b60008060008060006080868803121561356057600080fd5b853561356b816134d4565b9450602086013561357b816134d4565b935060408601359250606086013567ffffffffffffffff81111561359e57600080fd5b6135aa88828901613506565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126135e257600080fd5b8135602067ffffffffffffffff808311156135ff576135ff6135bb565b8260051b604051601f19603f83011681018181108482111715613624576136246135bb565b60405293845285810183019383810192508785111561364257600080fd5b83870191505b8482101561366157813583529183019190830190613648565b979650505050505050565b6000806040838503121561367f57600080fd5b82359150602083013567ffffffffffffffff81111561369d57600080fd5b6136a9858286016135d1565b9150509250929050565b600080604083850312156136c657600080fd5b50508035926020909101359150565b801515811461176757600080fd5b6000602082840312156136f557600080fd5b8135610d61816136d5565b60006020828403121561371257600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061374d57634e487b7160e01b600052602160045260246000fd5b9052565b81516001600160a01b031681526102408101602083015161377d60208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e08301516137c360e084018215159052565b50610100838101519083015261012080840151908301526101408084015190830152610160808401519083015261018080840151908301526101a080840151908301526101c080840151908301526101e08084015190830152610200808401511515908301526102208084015161383c8285018261372f565b505092915050565b6000806040838503121561385757600080fd5b8235613862816134d4565b946020939093013593505050565b6000806040838503121561388357600080fd5b823591506020830135613895816134d4565b809150509250929050565b60008060008060008060a087890312156138b957600080fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff8111156138ec57600080fd5b6138f889828a01613506565b979a9699509497509295939492505050565b6000806000806080858703121561392057600080fd5b843561392b816134d4565b935060208501359250604085013563ffffffff8116811461394b57600080fd5b9150606085013567ffffffffffffffff8116811461396857600080fd5b939692955090935050565b60808101613981828761372f565b931515602082015260408101929092521515606090910152919050565b600080604083850312156139b157600080fd5b823567ffffffffffffffff8111156139c857600080fd5b6139d4858286016135d1565b9250506020830135613895816134d4565b600080602083850312156139f857600080fd5b823567ffffffffffffffff80821115613a1057600080fd5b818501915085601f830112613a2457600080fd5b813581811115613a3357600080fd5b8660208260051b8501011115613a4857600080fd5b60209290920196919550909350505050565b60608101613a68828661372f565b6001600160a01b0393909316602082015260400152919050565b60008060008060808587031215613a9857600080fd5b8435613aa3816134d4565b966020860135965060408601359560600135945092505050565b634e487b7160e01b600052601160045260246000fd5b600060018201613ae557613ae5613abd565b5060010190565b60208082526018908201527f696e76616c69642063726f776466756e64207374617475730000000000000000604082015260600190565b60008219821115613b3657613b36613abd565b500190565b6020808252600d908201526c6f6e6c7920747265617375727960981b604082015260600190565b600082821015613b7457613b74613abd565b500390565b600060208284031215613b8b57600080fd5b8151610d61816134d4565b60018060a01b038451168152602084015160208201526040840151604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f1916010192915050565b600060208284031215613bfb57600080fd5b5051919050565b60208082526016908201527568617665206d6f76656420746f20747265617375727960501b604082015260600190565b6020808252600b908201526a1d1c9e535d5b0819985a5b60aa1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b82815260408101610d61602083018461372f565b60208082526010908201526f696e76616c6964207175616e7469747960801b604082015260600190565b6000816000190483118215151615613cc557613cc5613abd565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613cef57613cef613cca565b500690565b600082613d0357613d03613cca565b500490565b600060208284031215613d1a57600080fd5b8151610d61816136d556fe365a3d0a71be5f440c8224437355d5bd81a703759bf906e441902272bfbafcb3a26469706673582212204c774e89a196b0ab7acddaf9d634f6197fc47edc6b65e68de3b190f5e0d2607964736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000435bf54516dc869dc440042566972122e765147d0000000000000000000000003b4331d3c0e707ab067bfcf290cfa8e068b7e5be000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990900000000000000000000000000000000000000000000000000000000000002288af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000186a0
-----Decoded View---------------
Arg [0] : treasury_ (address): 0x435bf54516dC869dc440042566972122E765147d
Arg [1] : trader_ (address): 0x3B4331d3C0e707Ab067Bfcf290Cfa8E068b7e5Be
Arg [2] : vrfCoordinator_ (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [3] : vrfSubId_ (uint64): 552
Arg [4] : vrfKeyHash_ (bytes32): 0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [5] : vrfCBGasLimit_ (uint32): 100000
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000435bf54516dc869dc440042566972122e765147d
Arg [1] : 0000000000000000000000003b4331d3c0e707ab067bfcf290cfa8e068b7e5be
Arg [2] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000228
Arg [4] : 8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [5] : 00000000000000000000000000000000000000000000000000000000000186a0
Deployed Bytecode Sourcemap
71741:23990:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72590:25;;;;;;;;;;;;;;;;;;;160::1;;;148:2;133:18;72590:25:0;;;;;;;;75333:248;;;;;;;;;;-1:-1:-1;75333:248:0;;;;;:::i;:::-;;:::i;:::-;;94764:328;;;;;;;;;;-1:-1:-1;94764:328:0;;;;;:::i;:::-;-1:-1:-1;;;94764:328:0;;;;;;;;;;;-1:-1:-1;;;;;;1857:33:1;;;1839:52;;1827:2;1812:18;94764:328:0;1695:202:1;72055:21:0;;;;;;;;;;-1:-1:-1;72055:21:0;;;;-1:-1:-1;;;;;72055:21:0;;;;;;-1:-1:-1;;;;;2175:32:1;;;2157:51;;2145:2;2130:18;72055:21:0;2011:203:1;75894:161:0;;;;;;;;;;-1:-1:-1;75894:161:0;;;;;:::i;:::-;;:::i;35077:261::-;;;;;;;;;;-1:-1:-1;35077:261:0;;;;;:::i;:::-;;:::i;78712:511::-;;;;;;:::i;:::-;;:::i;74445:110::-;;;;;;;;;;-1:-1:-1;74445:110:0;;;;;:::i;:::-;;:::i;72385:31::-;;;;;;;;;;;;;;;;72561:22;;;;;;;;;;-1:-1:-1;72561:22:0;;;;-1:-1:-1;;;72561:22:0;;;;;;;;;4657:18:1;4645:31;;;4627:50;;4615:2;4600:18;72561:22:0;4483:200:1;72083:19:0;;;;;;;;;;;;;;;;72734:42;;;;;;;;;;-1:-1:-1;72734:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;85001:1189;;;;;;;;;;-1:-1:-1;85001:1189:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;74748:311::-;;;;;;;;;;-1:-1:-1;74748:311:0;;;;;:::i;:::-;;:::i;76603:242::-;;;;;;;;;;-1:-1:-1;76603:242:0;;;;;:::i;:::-;;:::i;86198:315::-;;;;;;;;;;-1:-1:-1;86198:315:0;;;;;:::i;:::-;;:::i;72134:26::-;;;;;;;;;;;;;;;;79231:1997;;;;;;;;;;-1:-1:-1;79231:1997:0;;;;;:::i;:::-;;:::i;87906:809::-;;;;;;;;;;-1:-1:-1;87906:809:0;;;;;:::i;:::-;;:::i;:::-;;;;8655:14:1;;8648:22;8630:41;;8702:2;8687:18;;8680:34;;;;8603:18;87906:809:0;8462:258:1;83594:942:0;;;;;;;;;;-1:-1:-1;83594:942:0;;;;;:::i;:::-;;:::i;75589:297::-;;;;;;;;;;-1:-1:-1;75589:297:0;;;;;:::i;:::-;;:::i;72025:23::-;;;;;;;;;;-1:-1:-1;72025:23:0;;;;-1:-1:-1;;;;;72025:23:0;;;2852:103;;;;;;;;;;;;;:::i;76236:359::-;;;;;;;;;;-1:-1:-1;76236:359:0;;;;;:::i;:::-;;:::i;86995:903::-;;;;;;;;;;-1:-1:-1;86995:903:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;77020:251::-;;;;;;;;;;-1:-1:-1;77020:251:0;;;;;:::i;:::-;;:::i;2204:87::-;;;;;;;;;;-1:-1:-1;2250:7:0;2277:6;-1:-1:-1;;;;;2277:6:0;2204:87;;72206:41;;;;;;;;;;;;;;;;75204:121;;;;;;;;;;-1:-1:-1;75204:121:0;;;;;:::i;:::-;;:::i;82515:474::-;;;;;;;;;;-1:-1:-1;82515:474:0;;;;;:::i;:::-;;:::i;72525:29::-;;;;;;;;;;-1:-1:-1;72525:29:0;;;;-1:-1:-1;;;;;72525:29:0;;;72290:39;;;;;;;;;;-1:-1:-1;72290:39:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;72290:39:0;;;72336:40;;;;;;;;;;-1:-1:-1;72336:40:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;10510:14:1;;10503:22;10485:41;;10473:2;10458:18;72336:40:0;10345:187:1;76063:165:0;;;;;;;;;;-1:-1:-1;76063:165:0;;;;;:::i;:::-;;:::i;74563:177::-;;;;;;;;;;-1:-1:-1;74563:177:0;;;;;:::i;:::-;;:::i;82997:589::-;;;;;;;;;;-1:-1:-1;82997:589:0;;;;;:::i;:::-;;:::i;72622:27::-;;;;;;;;;;-1:-1:-1;72622:27:0;;;;;;;;;;;11331:10:1;11319:23;;;11301:42;;11289:2;11274:18;72622:27:0;11157:192:1;84544:449:0;;;;;;;;;;-1:-1:-1;84544:449:0;;;;;:::i;:::-;;:::i;75067:129::-;;;;;;;;;;-1:-1:-1;75067:129:0;;;;;:::i;:::-;;:::i;76853:159::-;;;;;;;;;;-1:-1:-1;76853:159:0;;;;;:::i;:::-;;:::i;86521:466::-;;;;;;;;;;-1:-1:-1;86521:466:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;81236:1271::-;;;;;;;;;;-1:-1:-1;81236:1271:0;;;;;:::i;:::-;;:::i;72478:38::-;;;;;;;;;;-1:-1:-1;72478:38:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;3110:201;;;;;;;;;;-1:-1:-1;3110:201:0;;;;;:::i;:::-;;:::i;77279:1425::-;;;;;;:::i;:::-;;:::i;72111:16::-;;;;;;;;;;-1:-1:-1;72111:16:0;;;;;;;;72256:27;;;;;;;;;;;;;;;;75333:248;2090:13;:11;:13::i;:::-;75440:11:::1;::::0;;75432:20:::1;::::0;;;:7:::1;:20;::::0;;;;;;;:28;;-1:-1:-1;;;;;;75432:28:0::1;-1:-1:-1::0;;;;;75432:28:0;::::1;::::0;;::::1;::::0;;;75483:11;;75471:24;;:11:::1;:24:::0;;;;;;:31;;-1:-1:-1;;75471:31:0::1;-1:-1:-1::0;75471:31:0;;::::1;::::0;;;75531:11;;75518:31;;12400:51:1;;;12467:18;;;12460:34;;;;12510:18;;12503:50;;;;75518:31:0::1;::::0;12388:2:1;12373:18;75518:31:0::1;;;;;;;75560:11;:13:::0;;;:11:::1;:13;::::0;::::1;:::i;:::-;;;;;;75333:248:::0;:::o;75894:161::-;2090:13;:11;:13::i;:::-;-1:-1:-1;;;;;75993:13:0;::::1;;::::0;;;:6:::1;:13;::::0;;;;;;;;:20;;-1:-1:-1;;75993:20:0::1;76009:4;75993:20:::0;;::::1;::::0;;;76029:18;;13004:51:1;;;13071:18;;;13064:50;76029:18:0::1;::::0;12977::1;76029::0::1;;;;;;;;75894:161:::0;:::o;35077:261::-;35177:10;-1:-1:-1;;;;;35191:14:0;35177:28;;35173:111;;35223:53;;-1:-1:-1;;;35223:53:0;;35249:10;35223:53;;;13337:34:1;-1:-1:-1;;;;;35261:14:0;13407:15:1;13387:18;;;13380:43;13272:18;;35223:53:0;;;;;;;;35173:111;35290:42;35309:9;35320:11;35290:18;:42::i;:::-;35077:261;;:::o;78712:511::-;73715:4;;;;73707:29;;;;-1:-1:-1;;;73707:29:0;;13636:2:1;73707:29:0;;;13618:21:1;13675:2;13655:18;;;13648:30;-1:-1:-1;;;13694:18:1;;;13687:42;13746:18;;73707:29:0;13434:336:1;73707:29:0;23055:21:::1;:19;:21::i;:::-;78870:27:::2;78900:32;78920:11;78900:19;:32::i;:::-;78870:62;;78969:9;:24;;;78951:15;:42;78943:62;;;::::0;-1:-1:-1;;;78943:62:0;;13977:2:1;78943:62:0::2;::::0;::::2;13959:21:1::0;14016:1;13996:18;;;13989:29;-1:-1:-1;;;14034:18:1;;;14027:37;14081:18;;78943:62:0::2;13775:330:1::0;78943:62:0::2;79044:22;79024:16;::::0;::::2;::::0;::::2;;:42;::::0;::::2;;;;;;:::i;:::-;;79016:79;;;;-1:-1:-1::0;;;79016:79:0::2;;;;;;;:::i;:::-;79114:11;79129:1;79114:16:::0;79106:49:::2;;;::::0;-1:-1:-1;;;79106:49:0;;14665:2:1;79106:49:0::2;::::0;::::2;14647:21:1::0;14704:2;14684:18;;;14677:30;-1:-1:-1;;;14723:18:1;;;14716:50;14783:18;;79106:49:0::2;14463:344:1::0;79106:49:0::2;79168:47;79179:11;79192:9;79203:11;79168:10;:47::i;:::-;78859:364;23099:20:::1;22493:1:::0;23619:22;;23436:213;74445:110;2090:13;:11;:13::i;:::-;74535:4:::1;:12:::0;;-1:-1:-1;;74535:12:0::1;::::0;::::1;;::::0;;;::::1;::::0;;74445:110::o;85001:1189::-;85093:23;;:::i;:::-;85134:27;85164:32;85184:11;85164:19;:32::i;:::-;85240:663;;;;;;;;85271:17;;-1:-1:-1;;;;;85271:17:0;;;85240:663;;85271:17;85303:15;;;;85240:663;;;;85333:16;;;;85240:663;;;;;;;85364:33;;;;85240:663;;;;85412:20;;;;;85240:663;;;;85447:24;;;;85240:663;;;;85488:25;;;;85240:663;;;;85528:20;;;;;;;;85240:663;;;;;;85565:20;;;;85271:17;85240:663;;;85602:17;;;;85240:663;;;;85634:17;;;;85240:663;;;;85666:20;;;;85240:663;;;;85701:21;;;;85240:663;;;;85737:24;;;;85240:663;;;;85776:17;;;;85240:663;;;;85810:17;;;;85240:663;;;;85842:19;;;;;;85240:663;;;;;;85876:16;;;;85134:62;;-1:-1:-1;85209:28:0;;85240:663;;;;85876:16;;;85240:663;;;;;;;:::i;:::-;;;85209:694;-1:-1:-1;85940:22:0;85920:16;;;;;;:42;;;;;;;;:::i;:::-;;:89;;;;;85985:9;:24;;;85966:15;:43;;85920:89;85916:243;;;86040:23;86026:11;;;:37;86128:19;;86101:24;;;;:46;;86128:19;86101:46;:::i;:::-;86078:20;;;:69;85916:243;86178:4;85001:1189;-1:-1:-1;;;85001:1189:0:o;74748:311::-;2090:13;:11;:13::i;:::-;74876:20:::1;74900:1;74876:25:::0;74868:67:::1;;;::::0;-1:-1:-1;;;74868:67:0;;15147:2:1;74868:67:0::1;::::0;::::1;15129:21:1::0;15186:2;15166:18;;;15159:30;15225:31;15205:18;;;15198:59;15274:18;;74868:67:0::1;14945:353:1::0;74868:67:0::1;74946:19;:42:::0;;;75004:47:::1;::::0;160:25:1;;;75004:47:0::1;::::0;148:2:1;133:18;75004:47:0::1;14:177:1::0;76603:242:0;73821:8;;-1:-1:-1;;;;;73821:8:0;73807:10;:22;73799:48;;;;-1:-1:-1;;;73799:48:0;;;;;;;:::i;:::-;76744:7:::1;;76734:6;:17;;76726:44;;;::::0;-1:-1:-1;;;76726:44:0;;15847:2:1;76726:44:0::1;::::0;::::1;15829:21:1::0;15886:2;15866:18;;;15859:30;-1:-1:-1;;;15905:18:1;;;15898:44;15959:18;;76726:44:0::1;15645:338:1::0;76726:44:0::1;76792:6;76781:7;;:17;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;76809:28:0::1;::::0;-1:-1:-1;;;;;76809:20:0;::::1;::::0;:28;::::1;;;::::0;76830:6;;76809:28:::1;::::0;;;76830:6;76809:20;:28;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;76603:242:::0;;:::o;86198:315::-;86317:4;86339:27;86369:32;86389:11;86369:19;:32::i;:::-;86339:62;-1:-1:-1;86414:10:0;86447:35;:22;;;86477:4;86447:29;:35::i;:::-;86435:47;-1:-1:-1;;;;86198:315:0;;;;;:::o;79231:1997::-;73930:6;;-1:-1:-1;;;;;73930:6:0;73916:10;:20;73908:44;;;;-1:-1:-1;;;73908:44:0;;16320:2:1;73908:44:0;;;16302:21:1;16359:2;16339:18;;;16332:30;-1:-1:-1;;;16378:18:1;;;16371:41;16429:18;;73908:44:0;16118:335:1;73908:44:0;23055:21:::1;:19;:21::i;:::-;79446:27:::2;79476:32;79496:11;79476:19;:32::i;:::-;79446:62;;79545:9;:24;;;79527:15;:42;79519:62;;;::::0;-1:-1:-1;;;79519:62:0;;13977:2:1;79519:62:0::2;::::0;::::2;13959:21:1::0;14016:1;13996:18;;;13989:29;-1:-1:-1;;;14034:18:1;;;14027:37;14081:18;;79519:62:0::2;13775:330:1::0;79519:62:0::2;79620:22;79600:16;::::0;::::2;::::0;::::2;;:42;::::0;::::2;;;;;;:::i;:::-;;79592:79;;;;-1:-1:-1::0;;;79592:79:0::2;;;;;;;:::i;:::-;79697:15;::::0;::::2;::::0;-1:-1:-1;;;;;79697:15:0::2;79690:23;::::0;;;:6:::2;:23;::::0;;;;;::::2;;79682:49;;;::::0;-1:-1:-1;;;79682:49:0;;16660:2:1;79682:49:0::2;::::0;::::2;16642:21:1::0;16699:2;16679:18;;;16672:30;-1:-1:-1;;;16718:18:1;;;16711:43;16771:18;;79682:49:0::2;16458:337:1::0;79682:49:0::2;79802:20;::::0;::::2;::::0;79764:33:::2;::::0;::::2;::::0;:59:::2;::::0;:37:::2;:59::i;:::-;79750:10;:73;;79742:105;;;::::0;-1:-1:-1;;;79742:105:0;;17002:2:1;79742:105:0::2;::::0;::::2;16984:21:1::0;17041:2;17021:18;;;17014:30;-1:-1:-1;;;17060:18:1;;;17053:49;17119:18;;79742:105:0::2;16800:343:1::0;79742:105:0::2;79874:15;::::0;::::2;::::0;79866:41:::2;::::0;-1:-1:-1;;;79866:41:0;;::::2;::::0;::::2;160:25:1::0;;;79919:4:0::2;::::0;-1:-1:-1;;;;;79874:15:0::2;::::0;79866:32:::2;::::0;133:18:1;;79866:41:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;79866:58:0::2;::::0;79858:93:::2;;;::::0;-1:-1:-1;;;79858:93:0;;17606:2:1;79858:93:0::2;::::0;::::2;17588:21:1::0;17645:2;17625:18;;;17618:30;-1:-1:-1;;;17664:18:1;;;17657:52;17726:18;;79858:93:0::2;17404:346:1::0;79858:93:0::2;79964:13;79980:16:::0;;;:7:::2;:16;::::0;;;;;-1:-1:-1;;;;;79980:16:0::2;::::0;80007:53:::2;;;::::0;-1:-1:-1;;;80007:53:0;;17957:2:1;80007:53:0::2;::::0;::::2;17939:21:1::0;17996:2;17976:18;;;17969:30;-1:-1:-1;;;18015:18:1;;;18008:51;18076:18;;80007:53:0::2;17755:345:1::0;80007:53:0::2;80079:20;::::0;;;:11:::2;:20;::::0;;;;;::::2;;80071:53;;;::::0;-1:-1:-1;;;80071:53:0;;18307:2:1;80071:53:0::2;::::0;::::2;18289:21:1::0;18346:2;18326:18;;;18319:30;-1:-1:-1;;;18365:18:1;;;18358:50;18425:18;;80071:53:0::2;18105:344:1::0;80071:53:0::2;80169:101;::::0;;::::2;::::0;::::2;::::0;;80197:15:::2;::::0;::::2;::::0;-1:-1:-1;;;;;80197:15:0;;::::2;80169:101:::0;;::::2;::::0;::::2;::::0;;;;;;;;;80287:92;;-1:-1:-1;;;80287:92:0;;80169:101;;80287:20;::::2;::::0;::::2;::::0;80249:10;;80287:92:::2;::::0;80169:101;;80364:4;;;;80287:92:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;80283:938;;;::::0;;;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81174:35;81196:12;81174:21;:35::i;:::-;81125:96;80283:938;;;80411:14:::0;;80403:40:::2;::::0;-1:-1:-1;;;80403:40:0;;::::2;::::0;::::2;160:25:1::0;;;80455:4:0::2;::::0;-1:-1:-1;;;;;80403:31:0::2;::::0;::::2;::::0;133:18:1;;80403:40:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;80403:57:0::2;;80395:82;;;::::0;-1:-1:-1;;;80395:82:0;;19346:2:1;80395:82:0::2;::::0;::::2;19328:21:1::0;19385:2;19365:18;;;19358:30;-1:-1:-1;;;19404:18:1;;;19397:42;19456:18;;80395:82:0::2;19144:336:1::0;80395:82:0::2;80492:16;::::0;::::2;:41:::0;;-1:-1:-1;;80492:41:0::2;80511:22;80492:41;::::0;;80594:19:::2;::::0;80576:37:::2;::::0;:15:::2;:37;:::i;:::-;80548:25;::::0;::::2;:65:::0;80628:17:::2;::::0;::::2;:27:::0;;;80670:17:::2;::::0;::::2;:27:::0;;;80712:20:::2;::::0;::::2;:33:::0;;;80760:38:::2;80775:11:::0;80548:9;80760:14:::2;:38::i;:::-;80858:14;::::0;80911:10:::2;::::0;80999:13:::2;::::0;80832:225:::2;::::0;-1:-1:-1;;;80832:225:0;;::::2;::::0;::::2;19736:25:1::0;;;;-1:-1:-1;;;80940:8:0;::::2;;;19777:18:1::0;;;19770:59;72688:1:0::2;19845:18:1::0;;;19838:47;80999:13:0::2;;19930:18:1::0;;;19923:43;80858:14:0;19982:19:1;;;19975:44;80815:14:0::2;::::0;-1:-1:-1;;;;;80858:14:0::2;::::0;80832:60:::2;::::0;19708:19:1;;80832:225:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81074:24;::::0;;;:13:::2;:24;::::0;;;;:38;;;-1:-1:-1;80283:938:0::2;79435:1793;;;23099:20:::1;22493:1:::0;23619:22;;23436:213;23099:20:::1;79231:1997:::0;;;;;;:::o;87906:809::-;88004:4;88010;88027:27;88057:32;88077:11;88057:19;:32::i;:::-;88104:20;;;;88027:62;;-1:-1:-1;88104:20:0;;88100:70;;;-1:-1:-1;88149:5:0;;;;-1:-1:-1;87906:809:0;-1:-1:-1;;87906:809:0:o;88100:70::-;88205:9;:25;;;88186:15;:44;;:189;;;-1:-1:-1;88268:22:0;88248:16;;;;;;:42;;;;;;;;:::i;:::-;;:126;;;;;88354:19;;88327:9;:24;;;:46;;;;:::i;:::-;88307:15;:67;;88248:126;88182:496;;;88401:12;88437:22;88417:16;;;;;;:42;;;;;;;;:::i;:::-;;:105;;;-1:-1:-1;88496:26:0;88476:16;;;;;;:46;;;;;;;;:::i;:::-;;88417:105;88416:146;;;;-1:-1:-1;88542:19:0;;;;;;88541:20;88416:146;88401:161;;88577:15;88595:28;88613:9;88595:17;:28::i;:::-;88646:7;;88577:46;;-1:-1:-1;87906:809:0;;-1:-1:-1;;;;87906:809:0:o;88182:496::-;-1:-1:-1;88698:5:0;;;;-1:-1:-1;87906:809:0;-1:-1:-1;;87906:809:0:o;83594:942::-;23055:21;:19;:21::i;:::-;83694:27:::1;83724:32;83744:11;83724:19;:32::i;:::-;83776:20;::::0;::::1;::::0;83694:62;;-1:-1:-1;83776:20:0::1;;83775:21;83767:56;;;;-1:-1:-1::0;;;83767:56:0::1;;;;;;;:::i;:::-;83834:40;83851:11;83864:9;83834:16;:40::i;:::-;83915:23;83895:16;::::0;::::1;::::0;::::1;;:43;::::0;::::1;;;;;;:::i;:::-;;:90;;;-1:-1:-1::0;83962:23:0::1;83942:16;::::0;::::1;::::0;::::1;;:43;::::0;::::1;;;;;;:::i;:::-;;83895:90;83887:127;;;;-1:-1:-1::0;;;83887:127:0::1;;;;;;;:::i;:::-;84057:10;84034:34;::::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;::::1;;84033:35;84025:70;;;::::0;-1:-1:-1;;;84025:70:0;;20772:2:1;84025:70:0::1;::::0;::::1;20754:21:1::0;20811:2;20791:18;;;20784:30;-1:-1:-1;;;20830:18:1;;;20823:52;20892:18;;84025:70:0::1;20570:346:1::0;84025:70:0::1;84109:8;::::0;84141:41:::1;:22;::::0;::::1;84171:10;84141:29;:41::i;:::-;84108:74;;;;84201:3;84193:34;;;::::0;-1:-1:-1;;;84193:34:0;;21123:2:1;84193:34:0::1;::::0;::::1;21105:21:1::0;21162:2;21142:18;;;21135:30;-1:-1:-1;;;21181:18:1;;;21174:48;21239:18;;84193:34:0::1;20921:342:1::0;84193:34:0::1;84240:10;84276:42;84297:9;:20;;;84276:13;:20;;:42;;;;:::i;:::-;84261:57:::0;;-1:-1:-1;84261:57:0;-1:-1:-1;84261:57:0;84329:27:::1;;;;-1:-1:-1::0;;;84329:27:0::1;;;;;;;:::i;:::-;84392:10;84369:34;::::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;:41;;-1:-1:-1;;84369:41:0::1;84406:4;84369:41;::::0;;84421:35;;::::1;;;::::0;84450:5;;84421:35;;84369:34;84421:35;84450:5;84392:10;84421:35;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;84472:56:0::1;::::0;;21839:25:1;;;84495:10:0::1;21895:2:1::0;21880:18;;21873:60;21949:18;;;21942:34;;;22007:2;21992:18;;21985:34;;;84472:56:0::1;::::0;21826:3:1;21811:19;84472:56:0::1;;;;;;;83683:853;;;;23099:20:::0;22493:1;23619:22;;23436:213;23099:20;83594:942;:::o;75589:297::-;2090:13;:11;:13::i;:::-;75692:7;;;::::1;::::0;:27:::1;;;75708:11;;75703:2;:16;75692:27;75684:56;;;::::0;-1:-1:-1;;;75684:56:0;;22232:2:1;75684:56:0::1;::::0;::::1;22214:21:1::0;22271:2;22251:18;;;22244:30;-1:-1:-1;;;22290:18:1;;;22283:46;22346:18;;75684:56:0::1;22030:340:1::0;75684:56:0::1;75759:15;::::0;;;:11:::1;:15;::::0;;;;;::::1;;75751:46;;;::::0;-1:-1:-1;;;75751:46:0;;22577:2:1;75751:46:0::1;::::0;::::1;22559:21:1::0;22616:2;22596:18;;;22589:30;-1:-1:-1;;;22635:18:1;;;22628:48;22693:18;;75751:46:0::1;22375:342:1::0;75751:46:0::1;75828:5;75810:15:::0;;;:11:::1;:15;::::0;;;;;;;:23;;-1:-1:-1;;75810:23:0::1;::::0;;75855:7:::1;:11:::0;;;;;;75849:29;;-1:-1:-1;;;;;75855:11:0;;::::1;12400:51:1::0;;12467:18;;;12460:34;;;12510:18;;12503:50;;;;75849:29:0::1;::::0;12388:2:1;12373:18;75849:29:0::1;12204:355:1::0;2852:103:0;2090:13;:11;:13::i;:::-;2917:30:::1;2944:1;2917:18;:30::i;:::-;2852:103::o:0;76236:359::-;2090:13;:11;:13::i;:::-;76442:14:::1;:32:::0;;76485:10:::1;:21:::0;;;;76517:13:::1;:33:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;76517:33:0;;::::1;::::0;;;::::1;::::0;;;76561:26:::1;;-1:-1:-1::0;;;76561:26:0::1;-1:-1:-1::0;;;;;;76561:26:0;;;-1:-1:-1;;;;;76442:32:0;;::::1;76561:26:::0;;;;::::1;::::0;;76236:359::o;86995:903::-;87110:15;87127:4;87133;87139;87161:27;87191:32;87211:11;87191:19;:32::i;:::-;87161:62;-1:-1:-1;87236:13:0;87292:26;87272:16;;;;;;:46;;;;;;;;:::i;:::-;;87268:119;;87371:4;-1:-1:-1;;;;;87346:29:0;:21;87357:9;87346:10;:21::i;:::-;-1:-1:-1;;;;;87346:29:0;;87335:40;;87268:119;87399:18;87448:35;:22;;;87478:4;87448:29;:35::i;:::-;87428:55;-1:-1:-1;87496:16:0;;-1:-1:-1;87551:26:0;87531:16;;;;;;:46;;;;;;;;:::i;:::-;;87527:273;;87626:24;;;;87608:43;;:13;;:17;:43::i;:::-;87594:57;;87527:273;;;87692:26;87673:16;;;;;;:45;;;;;;;;:::i;:::-;;87669:131;;;87767:20;;;;87749:39;;:13;;:17;:39::i;:::-;87735:53;;87669:131;87820:16;;;;-1:-1:-1;;;;;87861:28:0;;87820:16;87861:28;;;:22;;;;:28;;;;;;;87820:16;;;;;-1:-1:-1;87838:8:0;;-1:-1:-1;87848:11:0;-1:-1:-1;;87861:28:0;;-1:-1:-1;86995:903:0;;;;;;;:::o;77020:251::-;73821:8;;-1:-1:-1;;;;;73821:8:0;73807:10;:22;73799:48;;;;-1:-1:-1;;;73799:48:0;;;;;;;:::i;:::-;77162:6:::1;77157:107;77178:12;:19;77174:1;:23;77157:107;;;77219:33;77232:12;77245:1;77232:15;;;;;;;;:::i;:::-;;;;;;;77249:2;77219:12;:33::i;:::-;77199:3:::0;::::1;::::0;::::1;:::i;:::-;;;;77157:107;;75204:121:::0;2090:13;:11;:13::i;:::-;75301:6:::1;:16:::0;;-1:-1:-1;;;;;;75301:16:0::1;-1:-1:-1::0;;;;;75301:16:0;;;::::1;::::0;;;::::1;::::0;;75204:121::o;82515:474::-;23055:21;:19;:21::i;:::-;82616:27:::1;82646:32;82666:11;82646:19;:32::i;:::-;82616:62:::0;-1:-1:-1;82717:26:0::1;82697:16;::::0;::::1;::::0;::::1;;:46;::::0;::::1;;;;;;:::i;:::-;;82689:83;;;;-1:-1:-1::0;;;82689:83:0::1;;;;;;;:::i;:::-;82792:20;::::0;::::1;::::0;::::1;;82791:21;82783:56;;;;-1:-1:-1::0;;;82783:56:0::1;;;;;;;:::i;:::-;82882:10;82859:34;::::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;::::1;;82858:35;82850:74;;;::::0;-1:-1:-1;;;82850:74:0;;23056:2:1;82850:74:0::1;::::0;::::1;23038:21:1::0;23095:2;23075:18;;;23068:30;23134:28;23114:18;;;23107:56;23180:18;;82850:74:0::1;22854:350:1::0;82850:74:0::1;82935:46;82958:11;82971:9;82935:22;:46::i;:::-;82605:384;23099:20:::0;22493:1;23619:22;;23436:213;76063:165;2090:13;:11;:13::i;:::-;-1:-1:-1;;;;;76164:13:0;::::1;76180:5;76164:13:::0;;;:6:::1;:13;::::0;;;;;;;:21;;-1:-1:-1;;76164:21:0::1;::::0;;76201:19;;13004:51:1;;;13071:18;;;13064:50;;;;76201:19:0::1;::::0;12977:18:1;76201:19:0::1;12836:284:1::0;74563:177:0;2090:13;:11;:13::i;:::-;72194:5:::1;74665:7;:21;;74657:48;;;::::0;-1:-1:-1;;;74657:48:0;;23411:2:1;74657:48:0::1;::::0;::::1;23393:21:1::0;23450:2;23430:18;;;23423:30;-1:-1:-1;;;23469:18:1;;;23462:44;23523:18;;74657:48:0::1;23209:338:1::0;74657:48:0::1;74716:6;:16:::0;74563:177::o;82997:589::-;23055:21;:19;:21::i;:::-;83121:6:::1;83116:463;83133:23:::0;;::::1;83116:463;;;83178:27;83208:36;83228:12;;83241:1;83228:15;;;;;;;:::i;:::-;;;;;;;83208:19;:36::i;:::-;83178:66:::0;-1:-1:-1;83287:26:0::1;83267:16;::::0;::::1;::::0;::::1;;:46;::::0;::::1;;;;;;:::i;:::-;;83259:83;;;;-1:-1:-1::0;;;83259:83:0::1;;;;;;;:::i;:::-;83366:20;::::0;::::1;::::0;::::1;;83365:21;83357:56;;;;-1:-1:-1::0;;;83357:56:0::1;;;;;;;:::i;:::-;83460:10;83437:34;::::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;::::1;;83436:35;83428:74;;;::::0;-1:-1:-1;;;83428:74:0;;23056:2:1;83428:74:0::1;::::0;::::1;23038:21:1::0;23095:2;23075:18;;;23068:30;23134:28;23114:18;;;23107:56;23180:18;;83428:74:0::1;22854:350:1::0;83428:74:0::1;83517:50;83540:12;;83553:1;83540:15;;;;;;;:::i;:::-;;;;;;;83557:9;83517:22;:50::i;:::-;-1:-1:-1::0;83158:3:0;::::1;::::0;::::1;:::i;:::-;;;;83116:463;;84544:449:::0;2090:13;:11;:13::i;:::-;84637:27:::1;84667:32;84687:11;84667:19;:32::i;:::-;84637:62:::0;-1:-1:-1;84738:22:0::1;84718:16;::::0;::::1;::::0;::::1;;:42;::::0;::::1;;;;;;:::i;:::-;;84710:79;;;;-1:-1:-1::0;;;84710:79:0::1;;;;;;;:::i;:::-;84800:16;::::0;::::1;:42:::0;;-1:-1:-1;;84800:42:0::1;84819:23;84800:42;::::0;;84899:19:::1;::::0;84881:37:::1;::::0;:15:::1;:37;:::i;:::-;84853:25;::::0;::::1;:65:::0;84934:51:::1;::::0;-1:-1:-1;;;;;;;;;;;84934:51:0;::::1;::::0;84948:11;;84961:23:::1;::::0;84934:51:::1;:::i;:::-;;;;;;;;84626:367;84544:449:::0;:::o;75067:129::-;2090:13;:11;:13::i;:::-;75168:8:::1;:20:::0;;-1:-1:-1;;;;;;75168:20:0::1;-1:-1:-1::0;;;;;75168:20:0;;;::::1;::::0;;;::::1;::::0;;75067:129::o;76853:159::-;73821:8;;-1:-1:-1;;;;;73821:8:0;73807:10;:22;73799:48;;;;-1:-1:-1;;;73799:48:0;;;;;;;:::i;:::-;76975:29:::1;76988:11;77001:2;76975:12;:29::i;86521:466::-:0;86609:15;86626:7;86635:4;86657:27;86687:32;86707:11;86687:19;:32::i;:::-;86657:62;-1:-1:-1;86754:26:0;86734:16;;;;;;:46;;;;;;;;:::i;:::-;;86730:119;;86805:16;;;;;;-1:-1:-1;86805:16:0;;-1:-1:-1;86805:16:0;;-1:-1:-1;86797:40:0;;86730:119;86861:14;86878:21;86889:9;86878:10;:21::i;:::-;86954:24;;;;;86918:26;;-1:-1:-1;86861:38:0;;-1:-1:-1;86954:24:0;;-1:-1:-1;;86521:466:0;;;;;;:::o;81236:1271::-;23055:21;:19;:21::i;:::-;81337:27:::1;81367:32;81387:11;81367:19;:32::i;:::-;81419:20;::::0;::::1;::::0;81337:62;;-1:-1:-1;81419:20:0::1;;81418:21;81410:56;;;;-1:-1:-1::0;;;81410:56:0::1;;;;;;;:::i;:::-;81505:26;81485:16;::::0;::::1;::::0;::::1;;:46;::::0;::::1;;;;;;:::i;:::-;;81477:83;;;;-1:-1:-1::0;;;81477:83:0::1;;;;;;;:::i;:::-;81573:14;81590:21;81601:9;81590:10;:21::i;:::-;81573:38:::0;-1:-1:-1;81630:10:0::1;-1:-1:-1::0;;;;;81630:20:0;::::1;;81622:46;;;::::0;-1:-1:-1;;;81622:46:0;;24050:2:1;81622:46:0::1;::::0;::::1;24032:21:1::0;24089:2;24069:18;;;24062:30;-1:-1:-1;;;24108:18:1;;;24101:43;24161:18;;81622:46:0::1;23848:337:1::0;81622:46:0::1;81711:19;::::0;::::1;::::0;::::1;;81706:260;;81747:19;::::0;::::1;:26:::0;;-1:-1:-1;;81747:26:0::1;81769:4;81747:26:::0;;::::1;::::0;;;81796:15;::::1;::::0;81849:17:::1;::::0;::::1;::::0;81788:79:::1;::::0;-1:-1:-1;;;81788:79:0;;81834:4:::1;81788:79;::::0;::::1;24430:34:1::0;-1:-1:-1;;;;;24500:15:1;;;24480:18;;;24473:43;24532:18;;;24525:34;;;;81796:15:0;::::1;::::0;81788:37:::1;::::0;24365:18:1;;81788:79:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;81919:15:0::1;::::0;::::1;::::0;81936:17:::1;::::0;::::1;::::0;81887:67:::1;::::0;;24801:25:1;;;-1:-1:-1;;;;;24900:15:1;;;24895:2;24880:18;;24873:43;81919:15:0;;::::1;24932:18:1::0;;;24925:43;24999:2;24984:18;;24977:34;81887:67:0::1;::::0;24788:3:1;24773:19;81887:67:0::1;;;;;;;81706:260;-1:-1:-1::0;;;;;82011:30:0;::::1;;::::0;;;:22:::1;::::0;::::1;:30;::::0;;;;;::::1;;82006:494;;82058:18;82111:37;:22;::::0;::::1;82141:6:::0;82111:29:::1;:37::i;:::-;82210:24;::::0;::::1;::::0;82091:57;;-1:-1:-1;82164:8:0::1;::::0;-1:-1:-1;82164:8:0;;82189:46:::1;::::0;82091:57;;82189:20:::1;:46::i;:::-;82163:72;;;;82258:3;82250:27;;;;-1:-1:-1::0;;;82250:27:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;82294:30:0;::::1;;::::0;;;:22:::1;::::0;::::1;:30;::::0;;;;:37;;-1:-1:-1;;82294:37:0::1;82327:4;82294:37;::::0;;82350:10;;82346:83:::1;;82381:32;::::0;-1:-1:-1;;;;;82381:24:0;::::1;::::0;:32;::::1;;;::::0;82406:6;;82381:32:::1;::::0;;;82406:6;82381:24;:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;82346:83;82450:38;::::0;;25224:25:1;;;-1:-1:-1;;;;;25285:32:1;;25280:2;25265:18;;25258:60;25334:18;;;25327:34;;;82450:38:0::1;::::0;25212:2:1;25197:18;82450:38:0::1;;;;;;;82043:457;;;82006:494;81326:1181;;23099:20:::0;22493:1;23619:22;;23436:213;3110:201;2090:13;:11;:13::i;:::-;-1:-1:-1;;;;;3199:22:0;::::1;3191:73;;;::::0;-1:-1:-1;;;3191:73:0;;25574:2:1;3191:73:0::1;::::0;::::1;25556:21:1::0;25613:2;25593:18;;;25586:30;25652:34;25632:18;;;25625:62;-1:-1:-1;;;25703:18:1;;;25696:36;25749:19;;3191:73:0::1;25372:402:1::0;3191:73:0::1;3275:28;3294:8;3275:18;:28::i;77279:1425::-:0;73715:4;;;;73707:29;;;;-1:-1:-1;;;73707:29:0;;13636:2:1;73707:29:0;;;13618:21:1;13675:2;13655:18;;;13648:30;-1:-1:-1;;;13694:18:1;;;13687:42;13746:18;;73707:29:0;13434:336:1;73707:29:0;23055:21:::1;:19;:21::i;:::-;-1:-1:-1::0;;;;;77517:19:0;::::2;77509:45;;;::::0;-1:-1:-1;;;77509:45:0;;16660:2:1;77509:45:0::2;::::0;::::2;16642:21:1::0;16699:2;16679:18;;;16672:30;-1:-1:-1;;;16718:18:1;;;16711:43;16771:18;;77509:45:0::2;16458:337:1::0;77509:45:0::2;-1:-1:-1::0;;;;;77573:13:0;::::2;;::::0;;;:6:::2;:13;::::0;;;;;::::2;;77565:44;;;::::0;-1:-1:-1;;;77565:44:0;;25981:2:1;77565:44:0::2;::::0;::::2;25963:21:1::0;26020:2;26000:18;;;25993:30;-1:-1:-1;;;26039:18:1;;;26032:48;26097:18;;77565:44:0::2;25779:342:1::0;77565:44:0::2;77628:23;77655:1;77628:28:::0;77620:60:::2;;;::::0;-1:-1:-1;;;77620:60:0;;26328:2:1;77620:60:0::2;::::0;::::2;26310:21:1::0;26367:2;26347:18;;;26340:30;-1:-1:-1;;;26386:18:1;;;26379:49;26445:18;;77620:60:0::2;26126:343:1::0;77620:60:0::2;77717:14;77699:15;:32;77691:68;;;::::0;-1:-1:-1;;;77691:68:0;;26676:2:1;77691:68:0::2;::::0;::::2;26658:21:1::0;26715:2;26695:18;;;26688:30;26754:25;26734:18;;;26727:53;26797:18;;77691:68:0::2;26474:347:1::0;77691:68:0::2;77778:11;77793:1;77778:16:::0;77770:47:::2;;;::::0;-1:-1:-1;;;77770:47:0;;27028:2:1;77770:47:0::2;::::0;::::2;27010:21:1::0;27067:2;27047:18;;;27040:30;-1:-1:-1;;;27086:18:1;;;27079:48;27144:18;;77770:47:0::2;26826:342:1::0;77770:47:0::2;77871:15;::::0;77830:27:::2;77860::::0;;;:10:::2;:27;::::0;;;;77898:30;;77918:10:::2;-1:-1:-1::0;;;;;;77898:30:0;;::::2;;::::0;;77958:6:::2;::::0;;77939:16:::2;::::0;::::2;:25:::0;-1:-1:-1;77975:15:0;::::2;:23:::0;;;;::::2;-1:-1:-1::0;;;;;77975:23:0;::::2;;::::0;;;78009:33:::2;::::0;::::2;:59:::0;;;78079:24:::2;::::0;::::2;:41:::0;;;-1:-1:-1;;78131:25:0;;::::2;:36:::0;78178:16:::2;::::0;::::2;:41:::0;;-1:-1:-1;;78178:41:0::2;::::0;;78293:6;77860:27;;77830;;;78262:38:::2;::::0;78009:59;;78262:30:::2;:38::i;:::-;78232:68;;;;78319:3;78311:32;;;::::0;-1:-1:-1;;;78311:32:0;;27375:2:1;78311:32:0::2;::::0;::::2;27357:21:1::0;27414:2;27394:18;;;27387:30;-1:-1:-1;;;27433:18:1;;;27426:46;27489:18;;78311:32:0::2;27173:340:1::0;78311:32:0::2;78369:26;:10:::0;72194:5:::2;78369:14;:26::i;:::-;78406:20;::::0;::::2;:33:::0;;;78470:15:::2;::::0;78457:77:::2;::::0;;21839:25:1;;;-1:-1:-1;;;;;21900:32:1;;21895:2;21880:18;;21873:60;21949:18;;21942:34;;;22007:2;21992:18;;21985:34;;;78356:39:0;;-1:-1:-1;78457:77:0::2;::::0;21826:3:1;21811:19;78457:77:0::2;;;;;;;-1:-1:-1::0;;;;;;;;;;;78564:15:0::2;;78581:22;78550:54;;;;;;;:::i;:::-;;;;;;;;78617:51;78628:15;;78645:9;78656:11;78617:10;:51::i;:::-;78679:15;:17:::0;;;:15:::2;:17;::::0;::::2;:::i;:::-;;;;;;77498:1206;;;23099:20:::1;22493:1:::0;23619:22;;23436:213;23099:20:::1;77279:1425:::0;;;;:::o;2369:132::-;2250:7;2277:6;-1:-1:-1;;;;;2277:6:0;829:10;2433:23;2425:68;;;;-1:-1:-1;;;2425:68:0;;27720:2:1;2425:68:0;;;27702:21:1;;;27739:18;;;27732:30;27798:34;27778:18;;;27771:62;27850:18;;2425:68:0;27518:356:1;95152:576:0;95298:16;95317:24;;;:13;:24;;;;;;;95360:16;;;95352:48;;;;-1:-1:-1;;;95352:48:0;;28081:2:1;95352:48:0;;;28063:21:1;28120:2;28100:18;;;28093:30;-1:-1:-1;;;28139:18:1;;;28132:49;28198:18;;95352:48:0;27879:343:1;95352:48:0;95411:27;95441:32;95461:11;95441:19;:32::i;:::-;95411:62;;95504:11;95516:1;95504:14;;;;;;;;:::i;:::-;;;;;;;95484:9;:17;;:34;;;;95575:19;;95557:15;:37;;;;:::i;:::-;95529:25;;;:65;95605:16;;;:45;;-1:-1:-1;;95605:45:0;95624:26;95605:45;;;;;;95666:54;;-1:-1:-1;;;;;;;;;;;95666:54:0;;;95680:11;;95624:26;95666:54;:::i;:::-;;;;;;;;95287:441;;95152:576;;:::o;23135:293::-;22537:1;23269:7;;:19;23261:63;;;;-1:-1:-1;;;23261:63:0;;28429:2:1;23261:63:0;;;28411:21:1;28468:2;28448:18;;;28441:30;28507:33;28487:18;;;28480:61;28558:18;;23261:63:0;28227:355:1;23261:63:0;22537:1;23402:7;:18;23135:293::o;90644:316::-;90745:17;90802:1;90788:11;:15;:48;;;;;90821:15;;90807:11;:29;90788:48;90780:81;;;;-1:-1:-1;;;90780:81:0;;28789:2:1;90780:81:0;;;28771:21:1;28828:2;28808:18;;;28801:30;-1:-1:-1;;;28847:18:1;;;28840:50;28907:18;;90780:81:0;28587:344:1;90780:81:0;-1:-1:-1;90872:27:0;90902:23;;;:10;:23;;;;;;90644:316::o;89854:782::-;90049:20;;;;90000:8;;90049:37;;90077:8;90049:27;:37::i;:::-;90025:20;;;90019:67;;-1:-1:-1;90019:67:0;90097:32;;;;-1:-1:-1;;;90097:32:0;;;;;;;:::i;:::-;90180:20;;;;90142:11;;90180:37;;90208:8;90180:27;:37::i;:::-;90164:53;;-1:-1:-1;90164:53:0;-1:-1:-1;90164:53:0;90228:32;;;;-1:-1:-1;;;90228:32:0;;;;;;;:::i;:::-;90271:56;90316:1;90320:6;90271:36;:56::i;:::-;90340:12;90377:41;:22;;;90407:10;90377:29;:41::i;:::-;90363:55;-1:-1:-1;90446:24:0;;-1:-1:-1;90363:55:0;90461:8;90446:14;:24::i;:::-;90429:41;;-1:-1:-1;90429:41:0;-1:-1:-1;90429:41:0;90481:32;;;;-1:-1:-1;;;90481:32:0;;;;;;;:::i;:::-;90526:47;:22;;;90553:10;90565:7;90526:26;:47::i;:::-;-1:-1:-1;90589:39:0;;;25224:25:1;;;90607:10:0;25280:2:1;25265:18;;25258:60;25334:18;;;25327:34;;;90589:39:0;;25212:2:1;25197:18;90589:39:0;;;;;;;89989:647;;;89854:782;;;:::o;62586:241::-;62668:4;;;;62726:50;62733:3;-1:-1:-1;;;;;62753:21:0;;62726:6;:50::i;:::-;62694:82;;-1:-1:-1;62694:82:0;-1:-1:-1;;;62586:241:0;;;;;;:::o;7291:98::-;7349:7;7376:5;7380:1;7376;:5;:::i;69944:381::-;70178:2;70166:10;70162:19;70243:10;70237:17;70220:15;70216:39;70293:13;70276:15;70269:38;91601:1269;91728:8;91738:16;91758:62;91786:9;:33;;;91758:9;:20;;;:27;;:62;;;;:::i;:::-;91727:93;;;;91839:3;91831:27;;;;-1:-1:-1;;;91831:27:0;;29656:2:1;91831:27:0;;;29638:21:1;29695:2;29675:18;;;29668:30;-1:-1:-1;;;29714:18:1;;;29707:41;29765:18;;91831:27:0;29454:335:1;91831:27:0;91898:9;:33;;;91875:9;:20;;;:56;;;;:::i;:::-;:61;91871:107;;91953:13;;;;:::i;:::-;;;;91871:107;91990:16;92038:65;92082:9;:20;;;92062:11;92039:9;:20;;;:34;;;;:::i;:::-;92038:43;;:65::i;:::-;92017:86;;-1:-1:-1;92017:86:0;-1:-1:-1;92017:86:0;92114:27;;;;-1:-1:-1;;;92114:27:0;;;;;;;:::i;:::-;92154:19;92208:40;92227:9;:20;;;92208:11;:18;;:40;;;;:::i;:::-;92184:64;;-1:-1:-1;92184:64:0;-1:-1:-1;92184:64:0;92259:27;;;;-1:-1:-1;;;92259:27:0;;30245:2:1;92259:27:0;;;30227:21:1;30284:2;30264:18;;;30257:30;-1:-1:-1;;;30303:18:1;;;30296:41;30354:18;;92259:27:0;30043:335:1;92259:27:0;92299:15;92345:49;92373:9;:20;;;92345:9;:20;;;:27;;:49;;;;:::i;:::-;92325:69;;;;;;;;92407:15;92453:85;92471:66;92516:9;:20;;;92471:40;92490:9;:20;;;92471:14;:18;;:40;;;;:::i;:::-;:44;;:66::i;:::-;92453:10;;:17;:85::i;:::-;92433:105;;-1:-1:-1;92433:105:0;-1:-1:-1;92433:105:0;92549:27;;;;-1:-1:-1;;;92549:27:0;;29656:2:1;92549:27:0;;;29638:21:1;29695:2;29675:18;;;29668:30;-1:-1:-1;;;29714:18:1;;;29707:41;29765:18;;92549:27:0;29454:335:1;92549:27:0;92606:7;;:26;;92621:10;92606:14;:26::i;:::-;92595:7;92589:43;;-1:-1:-1;92589:43:0;92643:27;;;;-1:-1:-1;;;92643:27:0;;30585:2:1;92643:27:0;;;30567:21:1;30624:2;30604:18;;;30597:30;-1:-1:-1;;;30643:18:1;;;30636:41;30694:18;;92643:27:0;30383:335:1;92643:27:0;92683:21;;;:35;;;92729:24;;;:41;;;92781:17;;;:30;;;92827:35;;;30897:25:1;;;30953:2;30938:18;;30931:34;;;92827:35:0;;30870:18:1;92827:35:0;;;;;;;91716:1154;;;;;;91601:1269;;:::o;93345:754::-;93455:4;93477:15;93503:12;93526:10;93547:11;93561:31;:9;:22;;:29;:31::i;:::-;93547:45;;93608:6;93603:217;93624:6;93620:1;:10;93603:217;;;93677:28;:22;;;93703:1;93677:25;:28::i;:::-;-1:-1:-1;;;;;93725:28:0;;;;;;:22;;;:28;;;;;;93661:44;;-1:-1:-1;93661:44:0;-1:-1:-1;93725:28:0;;93720:89;;93774:19;93788:5;93774:19;;:::i;:::-;;;93720:89;93632:3;;;;:::i;:::-;;;;93603:217;;;-1:-1:-1;93856:22:0;93836:16;;;;;;:42;;;;;;;;:::i;:::-;;:105;;;-1:-1:-1;93915:26:0;93895:16;;;;;;:46;;;;;;;;:::i;:::-;;93836:105;93832:260;;;93999:10;93974:9;:24;;;:35;;;;:::i;:::-;93967:42;93345:754;-1:-1:-1;;;;;;93345:754:0:o;93832:260::-;94070:10;94049:9;:20;;;:31;;;;:::i;92878:459::-;93030:22;93010:16;;;;;;:42;;;;;;;;:::i;:::-;;:89;;;;;93075:9;:24;;;93056:15;:43;;93010:89;93006:324;;;93116:16;;;:42;;-1:-1:-1;;93116:42:0;93135:23;93116:42;;;93228:19;;93201:24;;;;:46;;93228:19;93201:46;:::i;:::-;93173:25;;;:74;93267:51;;-1:-1:-1;;;;;;;;;;;93267:51:0;;;93281:11;;93294:23;;93267:51;:::i;5091:503::-;5152:4;5158:7;5440:1;5445;5440:6;5436:28;;-1:-1:-1;5456:4:0;;-1:-1:-1;5462:1:0;5448:16;;5436:28;5491:5;;;5495:1;5491;:5;:1;5515:5;;;;:::i;:::-;;:10;5511:33;;5535:5;5542:1;5527:17;;;;;;;5511:33;5567:4;;5573:1;;-1:-1:-1;5091:503:0;-1:-1:-1;;;5091:503:0:o;3471:191::-;3545:16;3564:6;;-1:-1:-1;;;;;3581:17:0;;;-1:-1:-1;;;;;;3581:17:0;;;;;;3614:40;;3564:6;;;;;;;3614:40;;3545:16;3614:40;3534:128;3471:191;:::o;90968:625::-;91071:7;91096:12;91119:10;91140:11;91172:9;:20;;;91154:9;:17;;;:38;;;;:::i;:::-;:42;;91195:1;91154:42;:::i;:::-;91140:56;;91207:11;91221:31;:9;:22;;:29;:31::i;:::-;91207:45;;91268:6;91263:243;91284:8;91291:1;91284:6;:8;:::i;:::-;91280:1;:12;91263:243;;;91330:28;:22;;;91356:1;91330:25;:28::i;:::-;91314:44;;-1:-1:-1;91314:44:0;-1:-1:-1;91377:15:0;;;91373:67;;-1:-1:-1;91420:4:0;;90968:625;-1:-1:-1;;;;;90968:625:0:o;91373:67::-;91456:15;91466:5;91456:15;;:::i;:::-;;;91294:3;;;;:::i;:::-;;;;91263:243;;;-1:-1:-1;91528:35:0;91554:8;91561:1;91554:6;:8;:::i;:::-;91528:22;;;;:25;:35::i;:::-;-1:-1:-1;91518:45:0;90968:625;-1:-1:-1;;;;;;90968:625:0:o;88782:1064::-;88889:27;88919:32;88939:11;88919:19;:32::i;:::-;88971:20;;;;88889:62;;-1:-1:-1;88971:20:0;;88970:21;88962:56;;;;-1:-1:-1;;;88962:56:0;;;;;;;:::i;:::-;89029:40;89046:11;89059:9;89029:16;:40::i;:::-;89109:9;:25;;;89090:15;:44;;89082:81;;;;-1:-1:-1;;;89082:81:0;;31178:2:1;89082:81:0;;;31160:21:1;31217:2;31197:18;;;31190:30;31256:26;31236:18;;;31229:54;31300:18;;89082:81:0;30976:348:1;89082:81:0;89174:20;;;:27;;-1:-1:-1;;89174:27:0;89197:4;89174:27;;;;;;:20;;89255:16;;;;;;:42;;;;;;;;:::i;:::-;;:101;;;-1:-1:-1;89330:26:0;89310:16;;;;;;:46;;;;;;;;:::i;:::-;;89255:101;89254:138;;;;-1:-1:-1;89372:19:0;;;;;;89371:20;89254:138;89239:153;;89407:7;89403:201;;;89439:15;;;;89488:17;;;;89431:75;;-1:-1:-1;;;89431:75:0;;89477:4;89431:75;;;24430:34:1;-1:-1:-1;;;;;24500:15:1;;;24480:18;;;24473:43;24532:18;;;24525:34;;;;89439:15:0;;;89431:37;;24365:18:1;;89431:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;89557:15:0;;;;89574:17;;;;89526:66;;;24801:25:1;;;-1:-1:-1;;;;;24900:15:1;;;24895:2;24880:18;;24873:43;89557:15:0;;;24932:18:1;;;24925:43;24999:2;24984:18;;24977:34;89526:66:0;;24788:3:1;24773:19;89526:66:0;;;;;;;89403:201;89641:15;89659:28;89677:9;89659:17;:28::i;:::-;89641:46;-1:-1:-1;89702:14:0;;89698:141;;89733:32;;-1:-1:-1;;;;;89733:20:0;;;:32;;;;;89754:10;;89733:32;;;;89754:10;89733:20;:32;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89785:42:0;;;25224:25:1;;;-1:-1:-1;;;;;25285:32:1;;25280:2;25265:18;;25258:60;25334:18;;;25327:34;;;89785:42:0;;25212:2:1;25197:18;89785:42:0;;;;;;;;89698:141;88878:968;;;88782:1064;;:::o;94107:599::-;94242:8;;94274:41;:22;;;94304:10;94274:29;:41::i;:::-;94241:74;;;;94334:3;94326:34;;;;-1:-1:-1;;;94326:34:0;;21123:2:1;94326:34:0;;;21105:21:1;21162:2;21142:18;;;21135:30;-1:-1:-1;;;21181:18:1;;;21174:48;21239:18;;94326:34:0;20921:342:1;94326:34:0;94373:11;94411:46;94432:9;:24;;;94411:13;:20;;:46;;;;:::i;:::-;94395:62;;-1:-1:-1;94395:62:0;-1:-1:-1;94395:62:0;94468:27;;;;-1:-1:-1;;;94468:27:0;;;;;;;:::i;:::-;94531:10;94508:34;;;;:22;;;:34;;;;;:41;;-1:-1:-1;;94508:41:0;94545:4;94508:41;;;94564:10;;94560:79;;94591:36;;94599:10;;94591:36;;;;;94620:6;;94591:36;;;;94620:6;94599:10;94591:36;;;;;;;;;;;;;;;;;;;;;94560:79;94656:42;;;25224:25:1;;;94679:10:0;25280:2:1;25265:18;;25258:60;25334:18;;;25327:34;;;94656:42:0;;25212:2:1;25197:18;94656:42:0;25022:345:1;7690:98:0;7748:7;7775:5;7779:1;7775;:5;:::i;4368:222::-;4429:4;;4492:5;;;4516;;;4512:28;;;4531:5;4538:1;4523:17;;;;;;;68190:381;68287:10;;68283:281;;-1:-1:-1;;;;;68318:19:0;;68314:239;;68379:6;68366:9;:19;;68358:42;;;;-1:-1:-1;;;68358:42:0;;31656:2:1;68358:42:0;;;31638:21:1;31695:2;31675:18;;;31668:30;-1:-1:-1;;;31714:18:1;;;31707:40;31764:18;;68358:42:0;31454:334:1;68314:239:0;68449:61;;-1:-1:-1;;;68449:61:0;;68476:10;68449:61;;;24430:34:1;68496:4:0;24480:18:1;;;24473:43;24532:18;;;24525:34;;;-1:-1:-1;;;;;68449:26:0;;;;;24365:18:1;;68449:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68441:96;;;;-1:-1:-1;;;68441:96:0;;32245:2:1;68441:96:0;;;32227:21:1;32284:2;32264:18;;;32257:30;-1:-1:-1;;;32303:18:1;;;32296:52;32365:18;;68441:96:0;32043:346:1;60851:218:0;60974:4;60998:63;61002:3;-1:-1:-1;;;;;61022:21:0;;61054:5;60998:3;:63::i;:::-;60991:70;60851:218;-1:-1:-1;;;;60851:218:0:o;53046:305::-;53131:4;53173:16;;;:11;;;:16;;;;;;53131:4;;53173:16;53200:144;;53248:18;53257:3;53262;53248:8;:18::i;:::-;53240:39;-1:-1:-1;53276:1:0;;-1:-1:-1;53240:39:0;;-1:-1:-1;53240:39:0;53200:144;53320:4;;-1:-1:-1;53326:5:0;-1:-1:-1;53312:20:0;;5750:195;5811:4;5817:7;5866:1;5871;5866:6;5862:29;;-1:-1:-1;5882:5:0;;-1:-1:-1;5882:5:0;5874:17;;5862:29;5914:4;5924:1;5920;:5;;;;;:::i;:::-;;5906:20;;;;5750:195;;;;;:::o;6553:98::-;6611:7;6638:5;6642:1;6638;:5;:::i;4742:194::-;4803:4;4809:7;4862:1;4858;:5;4854:28;;;-1:-1:-1;4873:5:0;;-1:-1:-1;4873:5:0;4865:17;;4854:28;-1:-1:-1;4905:4:0;;4911:5;;;;;-1:-1:-1;4742:194:0:o;61734:122::-;61803:7;61830:18;61837:3;61830:6;:18::i;62204:235::-;62284:7;;;;62344:21;62347:3;62359:5;62344:2;:21::i;51341:211::-;51467:4;51484:16;;;:11;;;:16;;;;;:24;;;51526:18;51484:3;51496;51526:13;:18::i;51978:142::-;52065:4;52089:23;:3;52108;52089:18;:23::i;52215:125::-;52287:7;52314:18;:3;:16;:18::i;52705:194::-;52788:7;;;52831:19;:3;52844:5;52831:12;:19::i;:::-;52874:16;;;;:11;;;;;:16;;;;;;;;;52705:194;-1:-1:-1;;;;52705:194:0:o;41469:125::-;41539:4;41563:23;41568:3;41580:5;41563:4;:23::i;41987:140::-;42067:4;39853:19;;;:12;;;:19;;;;;;:24;;42091:28;39756:129;42213:117;42276:7;42303:19;42311:3;40054:18;;39971:109;42684:131;42758:7;42785:22;42789:3;42801:5;42785:3;:22::i;37660:414::-;37723:4;39853:19;;;:12;;;:19;;;;;;37740:327;;-1:-1:-1;37783:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;37966:18;;37944:19;;;:12;;;:19;;;;;;:40;;;;37999:11;;37740:327;-1:-1:-1;38050:5:0;38043:12;;40434:120;40501:7;40528:3;:11;;40540:5;40528:18;;;;;;;;:::i;:::-;;;;;;;;;40521:25;;40434:120;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;196:131:1:-;-1:-1:-1;;;;;271:31:1;;261:42;;251:70;;317:1;314;307:12;332:247;391:6;444:2;432:9;423:7;419:23;415:32;412:52;;;460:1;457;450:12;412:52;499:9;486:23;518:31;543:5;518:31;:::i;584:347::-;635:8;645:6;699:3;692:4;684:6;680:17;676:27;666:55;;717:1;714;707:12;666:55;-1:-1:-1;740:20:1;;783:18;772:30;;769:50;;;815:1;812;805:12;769:50;852:4;844:6;840:17;828:29;;904:3;897:4;888:6;880;876:19;872:30;869:39;866:59;;;921:1;918;911:12;936:754;1033:6;1041;1049;1057;1065;1118:3;1106:9;1097:7;1093:23;1089:33;1086:53;;;1135:1;1132;1125:12;1086:53;1174:9;1161:23;1193:31;1218:5;1193:31;:::i;:::-;1243:5;-1:-1:-1;1300:2:1;1285:18;;1272:32;1313:33;1272:32;1313:33;:::i;:::-;1365:7;-1:-1:-1;1419:2:1;1404:18;;1391:32;;-1:-1:-1;1474:2:1;1459:18;;1446:32;1501:18;1490:30;;1487:50;;;1533:1;1530;1523:12;1487:50;1572:58;1622:7;1613:6;1602:9;1598:22;1572:58;:::i;:::-;936:754;;;;-1:-1:-1;936:754:1;;-1:-1:-1;1649:8:1;;1546:84;936:754;-1:-1:-1;;;936:754:1:o;2219:127::-;2280:10;2275:3;2271:20;2268:1;2261:31;2311:4;2308:1;2301:15;2335:4;2332:1;2325:15;2351:902;2405:5;2458:3;2451:4;2443:6;2439:17;2435:27;2425:55;;2476:1;2473;2466:12;2425:55;2512:6;2499:20;2538:4;2561:18;2598:2;2594;2591:10;2588:36;;;2604:18;;:::i;:::-;2650:2;2647:1;2643:10;2682:2;2676:9;2745:2;2741:7;2736:2;2732;2728:11;2724:25;2716:6;2712:38;2800:6;2788:10;2785:22;2780:2;2768:10;2765:18;2762:46;2759:72;;;2811:18;;:::i;:::-;2847:2;2840:22;2897:18;;;2973:15;;;2969:24;;;2931:15;;;;-1:-1:-1;3005:15:1;;;3002:35;;;3033:1;3030;3023:12;3002:35;3069:2;3061:6;3057:15;3046:26;;3081:142;3097:6;3092:3;3089:15;3081:142;;;3163:17;;3151:30;;3201:12;;;;3114;;;;3081:142;;;3241:6;2351:902;-1:-1:-1;;;;;;;2351:902:1:o;3258:416::-;3351:6;3359;3412:2;3400:9;3391:7;3387:23;3383:32;3380:52;;;3428:1;3425;3418:12;3380:52;3464:9;3451:23;3441:33;;3525:2;3514:9;3510:18;3497:32;3552:18;3544:6;3541:30;3538:50;;;3584:1;3581;3574:12;3538:50;3607:61;3660:7;3651:6;3640:9;3636:22;3607:61;:::i;:::-;3597:71;;;3258:416;;;;;:::o;3679:248::-;3747:6;3755;3808:2;3796:9;3787:7;3783:23;3779:32;3776:52;;;3824:1;3821;3814:12;3776:52;-1:-1:-1;;3847:23:1;;;3917:2;3902:18;;;3889:32;;-1:-1:-1;3679:248:1:o;3932:118::-;4018:5;4011:13;4004:21;3997:5;3994:32;3984:60;;4040:1;4037;4030:12;4055:241;4111:6;4164:2;4152:9;4143:7;4139:23;4135:32;4132:52;;;4180:1;4177;4170:12;4132:52;4219:9;4206:23;4238:28;4260:5;4238:28;:::i;4688:180::-;4747:6;4800:2;4788:9;4779:7;4775:23;4771:32;4768:52;;;4816:1;4813;4806:12;4768:52;-1:-1:-1;4839:23:1;;4688:180;-1:-1:-1;4688:180:1:o;4969:127::-;5030:10;5025:3;5021:20;5018:1;5011:31;5061:4;5058:1;5051:15;5085:4;5082:1;5075:15;5101:243;5188:1;5181:5;5178:12;5168:143;;5233:10;5228:3;5224:20;5221:1;5214:31;5268:4;5265:1;5258:15;5296:4;5293:1;5286:15;5168:143;5320:18;;5101:243::o;5349:1780::-;5583:13;;-1:-1:-1;;;;;1968:31:1;1956:44;;5551:3;5536:19;;5655:4;5647:6;5643:17;5637:24;5670:54;5718:4;5707:9;5703:20;5689:12;-1:-1:-1;;;;;1968:31:1;1956:44;;1902:104;5670:54;;5780:4;5772:6;5768:17;5762:24;5755:4;5744:9;5740:20;5733:54;5843:4;5835:6;5831:17;5825:24;5818:4;5807:9;5803:20;5796:54;5906:4;5898:6;5894:17;5888:24;5881:4;5870:9;5866:20;5859:54;5969:4;5961:6;5957:17;5951:24;5944:4;5933:9;5929:20;5922:54;6032:4;6024:6;6020:17;6014:24;6007:4;5996:9;5992:20;5985:54;6088:4;6080:6;6076:17;6070:24;6103:53;6150:4;6139:9;6135:20;6119:14;4943:13;4936:21;4924:34;;4873:91;6103:53;-1:-1:-1;6175:6:1;6223:15;;;6217:22;6197:18;;;6190:50;6259:6;6307:15;;;6301:22;6281:18;;;6274:50;6343:6;6391:15;;;6385:22;6365:18;;;6358:50;6427:6;6475:15;;;6469:22;6449:18;;;6442:50;6511:6;6559:15;;;6553:22;6533:18;;;6526:50;6595:6;6643:15;;;6637:22;6617:18;;;6610:50;6679:6;6727:15;;;6721:22;6701:18;;;6694:50;6763:6;6811:15;;;6805:22;6785:18;;;6778:50;6847:6;6890:15;;;6884:22;4943:13;4936:21;6947:18;;;4924:34;6986:6;7029:16;;;7023:23;7055:68;7103:19;;;7023:23;7055:68;:::i;:::-;;;5349:1780;;;;:::o;7134:315::-;7202:6;7210;7263:2;7251:9;7242:7;7238:23;7234:32;7231:52;;;7279:1;7276;7269:12;7231:52;7318:9;7305:23;7337:31;7362:5;7337:31;:::i;:::-;7387:5;7439:2;7424:18;;;;7411:32;;-1:-1:-1;;;7134:315:1:o;7454:::-;7522:6;7530;7583:2;7571:9;7562:7;7558:23;7554:32;7551:52;;;7599:1;7596;7589:12;7551:52;7635:9;7622:23;7612:33;;7695:2;7684:9;7680:18;7667:32;7708:31;7733:5;7708:31;:::i;:::-;7758:5;7748:15;;;7454:315;;;;;:::o;7774:683::-;7880:6;7888;7896;7904;7912;7920;7973:3;7961:9;7952:7;7948:23;7944:33;7941:53;;;7990:1;7987;7980:12;7941:53;8026:9;8013:23;8003:33;;8083:2;8072:9;8068:18;8055:32;8045:42;;8134:2;8123:9;8119:18;8106:32;8096:42;;8185:2;8174:9;8170:18;8157:32;8147:42;;8240:3;8229:9;8225:19;8212:33;8268:18;8260:6;8257:30;8254:50;;;8300:1;8297;8290:12;8254:50;8339:58;8389:7;8380:6;8369:9;8365:22;8339:58;:::i;:::-;7774:683;;;;-1:-1:-1;7774:683:1;;-1:-1:-1;7774:683:1;;8416:8;;7774:683;-1:-1:-1;;;7774:683:1:o;8725:668::-;8809:6;8817;8825;8833;8886:3;8874:9;8865:7;8861:23;8857:33;8854:53;;;8903:1;8900;8893:12;8854:53;8942:9;8929:23;8961:31;8986:5;8961:31;:::i;:::-;9011:5;-1:-1:-1;9063:2:1;9048:18;;9035:32;;-1:-1:-1;9119:2:1;9104:18;;9091:32;9167:10;9154:24;;9142:37;;9132:65;;9193:1;9190;9183:12;9132:65;9216:7;-1:-1:-1;9275:2:1;9260:18;;9247:32;9323:18;9310:32;;9298:45;;9288:73;;9357:1;9354;9347:12;9288:73;8725:668;;;;-1:-1:-1;8725:668:1;;-1:-1:-1;;8725:668:1:o;9398:454::-;9622:3;9607:19;;9635:50;9611:9;9667:6;9635:50;:::i;:::-;9728:14;;9721:22;9716:2;9701:18;;9694:50;9775:2;9760:18;;9753:34;;;;9830:14;9823:22;9818:2;9803:18;;;9796:50;9398:454;;-1:-1:-1;9398:454:1:o;9857:483::-;9950:6;9958;10011:2;9999:9;9990:7;9986:23;9982:32;9979:52;;;10027:1;10024;10017:12;9979:52;10067:9;10054:23;10100:18;10092:6;10089:30;10086:50;;;10132:1;10129;10122:12;10086:50;10155:61;10208:7;10199:6;10188:9;10184:22;10155:61;:::i;:::-;10145:71;;;10266:2;10255:9;10251:18;10238:32;10279:31;10304:5;10279:31;:::i;10537:615::-;10623:6;10631;10684:2;10672:9;10663:7;10659:23;10655:32;10652:52;;;10700:1;10697;10690:12;10652:52;10740:9;10727:23;10769:18;10810:2;10802:6;10799:14;10796:34;;;10826:1;10823;10816:12;10796:34;10864:6;10853:9;10849:22;10839:32;;10909:7;10902:4;10898:2;10894:13;10890:27;10880:55;;10931:1;10928;10921:12;10880:55;10971:2;10958:16;10997:2;10989:6;10986:14;10983:34;;;11013:1;11010;11003:12;10983:34;11066:7;11061:2;11051:6;11048:1;11044:14;11040:2;11036:23;11032:32;11029:45;11026:65;;;11087:1;11084;11077:12;11026:65;11118:2;11110:11;;;;;11140:6;;-1:-1:-1;10537:615:1;;-1:-1:-1;;;;10537:615:1:o;11354:388::-;11562:2;11547:18;;11574:50;11551:9;11606:6;11574:50;:::i;:::-;-1:-1:-1;;;;;11660:32:1;;;;11655:2;11640:18;;11633:60;11724:2;11709:18;11702:34;11354:388;;-1:-1:-1;11354:388:1:o;11747:452::-;11833:6;11841;11849;11857;11910:3;11898:9;11889:7;11885:23;11881:33;11878:53;;;11927:1;11924;11917:12;11878:53;11966:9;11953:23;11985:31;12010:5;11985:31;:::i;:::-;12035:5;12087:2;12072:18;;12059:32;;-1:-1:-1;12138:2:1;12123:18;;12110:32;;12189:2;12174:18;12161:32;;-1:-1:-1;11747:452:1;-1:-1:-1;;;11747:452:1:o;12564:127::-;12625:10;12620:3;12616:20;12613:1;12606:31;12656:4;12653:1;12646:15;12680:4;12677:1;12670:15;12696:135;12735:3;12756:17;;;12753:43;;12776:18;;:::i;:::-;-1:-1:-1;12823:1:1;12812:13;;12696:135::o;14110:348::-;14312:2;14294:21;;;14351:2;14331:18;;;14324:30;14390:26;14385:2;14370:18;;14363:54;14449:2;14434:18;;14110:348::o;14812:128::-;14852:3;14883:1;14879:6;14876:1;14873:13;14870:39;;;14889:18;;:::i;:::-;-1:-1:-1;14925:9:1;;14812:128::o;15303:337::-;15505:2;15487:21;;;15544:2;15524:18;;;15517:30;-1:-1:-1;;;15578:2:1;15563:18;;15556:43;15631:2;15616:18;;15303:337::o;15988:125::-;16028:4;16056:1;16053;16050:8;16047:34;;;16061:18;;:::i;:::-;-1:-1:-1;16098:9:1;;15988:125::o;17148:251::-;17218:6;17271:2;17259:9;17250:7;17246:23;17242:32;17239:52;;;17287:1;17284;17277:12;17239:52;17319:9;17313:16;17338:31;17363:5;17338:31;:::i;18454:685::-;18737:1;18733;18728:3;18724:11;18720:19;18711:6;18705:13;18701:39;18690:9;18683:58;18797:4;18789:6;18785:17;18779:24;18772:4;18761:9;18757:20;18750:54;18860:4;18852:6;18848:17;18842:24;18835:4;18824:9;18820:20;18813:54;18903:3;18898:2;18887:9;18883:18;18876:31;18944:6;18938:3;18927:9;18923:19;18916:35;19002:6;18994;18988:3;18977:9;18973:19;18960:49;19059:1;19029:22;;;19053:3;19025:32;;;19018:43;;;;19122:2;19101:15;;;-1:-1:-1;;19097:29:1;19082:45;19078:55;;18454:685;-1:-1:-1;;18454:685:1:o;20030:184::-;20100:6;20153:2;20141:9;20132:7;20128:23;20124:32;20121:52;;;20169:1;20166;20159:12;20121:52;-1:-1:-1;20192:16:1;;20030:184;-1:-1:-1;20030:184:1:o;20219:346::-;20421:2;20403:21;;;20460:2;20440:18;;;20433:30;-1:-1:-1;;;20494:2:1;20479:18;;20472:52;20556:2;20541:18;;20219:346::o;21268:335::-;21470:2;21452:21;;;21509:2;21489:18;;;21482:30;-1:-1:-1;;;21543:2:1;21528:18;;21521:41;21594:2;21579:18;;21268:335::o;22722:127::-;22783:10;22778:3;22774:20;22771:1;22764:31;22814:4;22811:1;22804:15;22838:4;22835:1;22828:15;23552:291;23744:25;;;23732:2;23717:18;;23778:59;23833:2;23818:18;;23810:6;23778:59;:::i;28936:340::-;29138:2;29120:21;;;29177:2;29157:18;;;29150:30;-1:-1:-1;;;29211:2:1;29196:18;;29189:46;29267:2;29252:18;;28936:340::o;29281:168::-;29321:7;29387:1;29383;29379:6;29375:14;29372:1;29369:21;29364:1;29357:9;29350:17;29346:45;29343:71;;;29394:18;;:::i;:::-;-1:-1:-1;29434:9:1;;29281:168::o;29794:127::-;29855:10;29850:3;29846:20;29843:1;29836:31;29886:4;29883:1;29876:15;29910:4;29907:1;29900:15;29926:112;29958:1;29984;29974:35;;29989:18;;:::i;:::-;-1:-1:-1;30023:9:1;;29926:112::o;31329:120::-;31369:1;31395;31385:35;;31400:18;;:::i;:::-;-1:-1:-1;31434:9:1;;31329:120::o;31793:245::-;31860:6;31913:2;31901:9;31892:7;31888:23;31884:32;31881:52;;;31929:1;31926;31919:12;31881:52;31961:9;31955:16;31980:28;32002:5;31980:28;:::i
Swarm Source
ipfs://4c774e89a196b0ab7acddaf9d634f6197fc47edc6b65e68de3b190f5e0d26079
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.