Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60a06040 | 20756792 | 548 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
FairLaunchLimitBlockV3Factory
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2024-09-15
*/
// Sources flattened with hardhat v2.22.4 https://hardhat.org
// SPDX-License-Identifier: BUSL-1.1 AND MIT
// File @openzeppelin/contracts/utils/Context.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File @openzeppelin/contracts/access/Ownable.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling 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/token/ERC20/IERC20.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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/token/ERC20/extensions/IERC20Metadata.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// File @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// File @openzeppelin/contracts/utils/Address.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// File @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface 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.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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/security/ReentrancyGuard.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
// File contracts/FairLaunchLimitBlockV3Factory/IFairLaunch.sol
// Original license: SPDX_License_Identifier: MIT
pragma solidity ^0.8.19;
interface IFairLaunch {
event Deployed(address indexed addr, uint256 _type);
event FundEvent(
address indexed to,
uint256 ethAmount,
uint256 amountOfTokens
);
event LaunchEvent(
address indexed to,
uint256 amount,
uint256 ethAmount,
uint256 liquidity
);
event RefundEvent(address indexed from, uint256 amount, uint256 eth);
}
struct FairLaunchLimitAmountStruct {
uint256 price;
uint256 amountPerUnits;
uint256 totalSupply;
address launcher;
address uniswapRouter;
address uniswapFactory;
string name;
string symbol;
string meta;
uint256 eachAddressLimitEthers;
uint256 refundFeeRate;
address refundFeeTo;
}
struct FairLaunchLimitBlockStruct {
uint256 totalSupply;
address uniswapRouter;
address uniswapFactory;
string name;
string symbol;
string description;
string image;
string website;
string telegram;
string twitter;
string meta;
uint256 maxEthLmit;
uint256 afterBlock;
uint256 softTopCap;
uint256 refundFeeRate;
address refundFeeTo;
}
// File contracts/FairLaunchLimitBlockV3Factory/IMeme.sol
// Original license: SPDX_License_Identifier: MIT
pragma solidity ^0.8.19;
interface IMeme is IERC20Metadata {
function meta() external view returns (string memory);
}
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string internal _name;
string internal _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor() {
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
contract Meme is ERC20 {
string public meta;
string public description;
string public image;
string public website;
string public telegram;
string public twitter;
constructor() {}
function _initializeMeme(
string memory name,
string memory symbol,
string memory _description,
string memory _image,
string memory _website,
string memory _telegram,
string memory _twitter,
string memory _meta
) internal {
_name = name;
_symbol = symbol;
description = _description;
image = _image;
website = _website;
telegram = _telegram;
twitter = _twitter;
meta = _meta;
}
}
// File contracts/FairLaunchLimitBlockV3Factory/NoDelegateCall.sol
// Original license: SPDX_License_Identifier: BUSL-1.1
pragma solidity ^0.8.19;
/// @title Prevents delegatecall to a contract
/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract
abstract contract NoDelegateCall {
/// @dev The original address of this contract
address private immutable original;
constructor() {
// Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode.
// In other words, this variable won't change when it's checked at runtime.
original = address(this);
}
/// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method,
/// and the use of immutable means the address bytes are copied in every place the modifier is used.
function checkNotDelegateCall() private view {
require(address(this) == original);
}
/// @notice Prevents delegatecall into the modified method
modifier noDelegateCall() {
checkNotDelegateCall();
_;
}
}
// File contracts/FairLaunchLimitBlockV3Factory/FairLaunchLimitBlockV3.sol
// Original license: SPDX_License_Identifier: MIT
pragma solidity =0.8.24;
// IERC20
// import {FairLaunchLimitBlockV3Factory} from "./FairLaunchLimitBlockV3Factory.sol";
interface IUniLocker {
function lock(
address lpToken,
uint256 amountOrId,
uint256 unlockBlock
) external returns (uint256 id);
}
interface IUniswapV3Factory {
function getPool(
address tokenA,
address tokenB,
uint24 fee
) external view returns (address pool);
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external returns (address pool);
}
interface INonfungiblePositionManager {
function WETH9() external pure returns (address);
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
function mint(
MintParams calldata params
)
external
payable
returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
function createAndInitializePoolIfNecessary(
address token0,
address token1,
uint24 fee,
uint160 sqrtPriceX96
) external payable returns (address pool);
function refundETH() external payable;
}
contract FairLaunchLimitBlockTokenV3 is
IFairLaunch,
Meme,
ReentrancyGuard,
NoDelegateCall
{
using SafeERC20 for IERC20;
using Math for uint256;
// refund command
// before start, you can always refund
// send 0.0002 ether to the contract address to refund all ethers
uint256 public constant REFUND_COMMAND = 0.0002 ether;
// claim command
// after start, you can claim extra eth
// send 0.0002 ether to the contract address to claim extra eth
// uint256 public constant CLAIM_COMMAND = 0.0002 ether;
// start trading command
// if the untilBlockNumber reached, you can start trading with this command
// send 0.0005 ether to the contract address to start trading
// uint256 public constant START_COMMAND = 0.0005 ether;
// mint command
// if the untilBlockNumber reached, you can mint token with this command
// send 0.0001 ether to the contract address to get tokens
uint256 public constant MINT_COMMAND = 0.0001 ether;
// minimal fund
uint256 public constant MINIMAL_FUND = 0.000001 ether;
address public fairLaunchFactory;
// is trading started
bool public started;
address public uniswapPositionManager;
address public uniswapFactory;
uint256 public lockTokenId;
// fund balance
mapping(address => uint256) public fundBalanceOf;
// is address minted
mapping(address => bool) public minted;
// total dispatch amount
uint256 public totalDispatch;
// until block number
uint256 public untilBlockTimestamp;
uint256 public createTimestamp;
// total ethers funded
uint256 public totalEthers;
uint256 public maxEthLmit;
uint256 public involvedUser;
// soft top cap
uint256 public softTopCap;
// refund fee rate
uint256 public refundFeeRate;
// refund fee to
address public refundFeeTo;
// is address claimed extra eth
mapping(address => bool) public claimed;
// recipient must be a contract address of IUniLocker
address public locker;
// feePool
uint24 public poolFee;
// project owner, whill receive the locked lp
address public projectOwner;
constructor() {
fairLaunchFactory = msg.sender;
}
function initialize(
address _locker,
uint24 _poolFee,
address _projectOwner,
FairLaunchLimitBlockStruct memory params
) external {
require(msg.sender == fairLaunchFactory, 'Launch: FORBIDDEN'); // sufficient check
_initializeMeme(params.name, params.symbol, params.description, params.image, params.website, params.telegram, params.twitter, params.meta);
started = false;
totalDispatch = params.totalSupply;
_mint(address(this), totalDispatch);
// set uniswap router
uniswapPositionManager = params.uniswapRouter;
uniswapFactory = params.uniswapFactory;
meta = params.meta;
untilBlockTimestamp = params.afterBlock + block.timestamp;
createTimestamp = block.timestamp;
softTopCap = params.softTopCap;
maxEthLmit = params.maxEthLmit;
refundFeeRate = params.refundFeeRate;
refundFeeTo = params.refundFeeTo;
locker = _locker;
projectOwner = _projectOwner;
poolFee = _poolFee;
INonfungiblePositionManager _positionManager = INonfungiblePositionManager(
uniswapPositionManager
);
_initPool(_positionManager.WETH9(), softTopCap, _positionManager, true);
}
receive() external payable noDelegateCall {
if (msg.sender == uniswapPositionManager) {
return;
}
require( tx.origin == msg.sender, "FairMint: can not send command from contract." );
if(canStart()){
if (msg.value == REFUND_COMMAND) {
// before start, you can always refund
_refund();
}else if (msg.value == MINT_COMMAND) {
if(totalEthers >= softTopCap && !started){
_start();
}
_mintToken();
if(totalEthers > softTopCap){ _claimExtraETH();
}
(bool success, ) = msg.sender.call{
value: MINT_COMMAND
}("");
require(success, "FairMint: mint failed");
} else {
revert("FairMint: claim");
}
}else{
if (msg.value == REFUND_COMMAND) {
// before start, you can always refund
_refund();
} else {
// before start, any other value will be considered as fund
_fund();
}
}
}
struct UserStruct{ uint256 fundBalance; uint256 extraETH; uint256 mintTokenAmount; uint256 lockTokenId; bool claimed; bool minted; }
function getUserData(address addr) public view returns(UserStruct memory){
return UserStruct({
claimed: claimed[addr],
minted: minted[addr],
fundBalance: fundBalanceOf[addr],
extraETH: getExtraETH(addr),
mintTokenAmount: mightGet(addr),
lockTokenId: lockTokenId
});
}
function canStart() public view returns (bool) {
// return block.number >= untilBlockNumber || totalEthers >= softTopCap;
// eth balance of this contract is more than zero
return block.timestamp >= untilBlockTimestamp;
}
// get extra eth
function getExtraETH(address _addr) public view returns (uint256) {
if (totalEthers > softTopCap) {
uint256 claimAmount = (fundBalanceOf[_addr] *
(totalEthers - softTopCap)) / totalEthers;
return claimAmount;
}
return 0;
}
// claim extra eth
function _claimExtraETH() private nonReentrant {
// if the eth balance of this contract is more than soft top cap, withdraw it
// must after start
require(started, "FairMint: withdraw extra eth must after start");
require(softTopCap > 0, "FairMint: soft top cap must be set");
require(totalEthers > softTopCap, "FairMint: no extra eth");
uint256 extra = totalEthers - softTopCap;
uint256 fundAmount = fundBalanceOf[msg.sender];
require(fundAmount > 0, "FairMint: no fund");
require(!claimed[msg.sender], "FairMint: already claimed");
claimed[msg.sender] = true;
uint256 claimAmount = (fundAmount * extra) / totalEthers;
// send to msg sender
(bool success, ) = msg.sender.call{value: claimAmount}( "" );
require(success, "FairMint: withdraw failed");
}
// estimate how many tokens you might get
function mightGet(address account ) public view returns (uint256) {
if (totalEthers == 0 ) {
return 0;
}
uint256 _mintAmount = (totalDispatch * fundBalanceOf[account]) /
2 /
totalEthers;
return _mintAmount;
}
function _fund() private nonReentrant {
// require msg.value > 0.0001 ether
require(!started, "FairMint: already started");
require(msg.value >= MINIMAL_FUND, "FairMint: value too low");
require((msg.value + fundBalanceOf[msg.sender]) <= maxEthLmit, "FairMint: value too high");
if(fundBalanceOf[msg.sender] == 0){
involvedUser += 1;
}
FairLaunchLimitBlockV3Factory(fairLaunchFactory).addInvolveLaunchToken(msg.sender , msg.value);
fundBalanceOf[msg.sender] += msg.value;
totalEthers += msg.value;
emit FundEvent(msg.sender, msg.value, 0);
}
function _refund() private nonReentrant {
require(!started, "FairMint: already started");
address account = msg.sender;
uint256 amount = fundBalanceOf[account];
require(amount > 0, "FairMint: no fund");
fundBalanceOf[account] = 0;
totalEthers -= amount;
involvedUser -= 1;
FairLaunchLimitBlockV3Factory(fairLaunchFactory).removeInvolveLaunchToken(msg.sender , amount);
uint256 fee = (amount * refundFeeRate) / 10000;
assert(fee < amount);
if (fee > 0 && refundFeeTo != address(0)) {
(bool success, ) = refundFeeTo.call{value: fee}("");
require(success, "FairMint: refund fee failed");
}
(bool success1, ) = account.call{value: amount - fee + REFUND_COMMAND}(
""
);
require(success1, "FairMint: refund failed");
emit RefundEvent(account, 0, amount);
}
function _mintToken() private nonReentrant {
require(started, "FairMint: not started");
require(msg.sender == tx.origin, "FairMint: can not mint to contract.");
require(!minted[msg.sender], "FairMint: already minted");
minted[msg.sender] = true;
uint256 _mintAmount = mightGet(msg.sender);
require(_mintAmount > 0, "FairMint: mint amount is zero");
assert(_mintAmount <= totalDispatch / 2);
_transfer(address(this), msg.sender, _mintAmount);
}
function _start() private nonReentrant {
require(!started, "FairMint: already started");
require(balanceOf(address(this)) > 0, "FairMint: no balance");
INonfungiblePositionManager _positionManager = INonfungiblePositionManager(
uniswapPositionManager
);
address _weth = _positionManager.WETH9();
// address _poolAddress = IUniswapV3Factory(uniswapFactory).getPool(
// address(this),
// _weth,
// poolFee
// );
// require(
// _poolAddress == address(0),
// "FairMint: pool already exists, can not start, please refund"
// );
uint256 totalAdd = softTopCap;
_approve( address(this), uniswapPositionManager, type(uint256).max );
(address token0, address token1) = address(this) < _weth ? (address(this), _weth) : (_weth, address(this));
(uint256 amount0, uint256 amount1) = address(this) < _weth
? (totalDispatch / 2, totalAdd)
: (totalAdd, totalDispatch / 2);
(
uint256 tokenId,
uint128 liquidity,
uint256 _amount0,
uint256 _amount1
) = _mintLiquidity(
_positionManager,
token0,
token1,
amount0,
amount1,
totalAdd
);
started = true;
FairLaunchLimitBlockV3Factory(fairLaunchFactory).setUniswapLaunchToken(projectOwner);
emit LaunchEvent(address(this), _amount0, _amount1, liquidity);
// _positionManager.refundETH(); // dumplia
// lock lp into contract forever
if (locker != address(0)) {
IERC721(uniswapPositionManager).approve(locker, tokenId);
IUniLocker _locker = IUniLocker(locker);
uint256 _lockId = _locker.lock(
uniswapPositionManager,
tokenId,
type(uint256).max
);
lockTokenId = _lockId;
IERC721(locker).transferFrom(
address(this),
projectOwner,
_lockId
);
}
// (bool success, ) = msg.sender.call{value: START_COMMAND}("");
// require(success, "FairMint: mint failed");
}
function _mintLiquidity(
INonfungiblePositionManager _positionManager,
address token0,
address token1,
uint256 amount0,
uint256 amount1,
uint256 totalAdd
) private returns (uint256, uint128, uint256, uint256) {
INonfungiblePositionManager.MintParams
memory params = INonfungiblePositionManager.MintParams({
token0: token0,
token1: token1,
fee: poolFee,
//tickLower: -887250, // base -887220,
//tickUpper: 887250, // base 887220,
tickLower: -887220,
tickUpper: 887220,
amount0Desired: amount0,
amount1Desired: amount1,
amount0Min: (amount0 * 98) / 100,
amount1Min: (amount1 * 98) / 100,
recipient: locker == address(0) ? address(0) : address(this),
deadline: block.timestamp + 1 hours
});
(
uint256 _tokenId,
uint128 _liquidity,
uint256 _amount0,
uint256 _amount1
) = _positionManager.mint{value: totalAdd}(params);
_positionManager.refundETH();
return (_tokenId, _liquidity, _amount0, _amount1);
}
function _initPool(
address _weth,
uint256 totalAdd,
INonfungiblePositionManager _positionManager,
bool isInit
)
private
returns (
address token0,
address token1,
uint256 amount0,
uint256 amount1,
uint160 sqrtPriceX96
)
{
(token0, token1) = address(this) < _weth ? (address(this), _weth) : (_weth, address(this));
(amount0, amount1) = address(this) < _weth
? (totalDispatch / 2, totalAdd)
: (totalAdd, totalDispatch / 2);
if(isInit){
sqrtPriceX96 = getSqrtPriceX96(amount0, amount1);
_positionManager.createAndInitializePoolIfNecessary(
token0,
token1,
poolFee,
sqrtPriceX96
);
}
}
function getSqrtPriceX96(
uint256 amount0,
uint256 amount1
) internal pure returns (uint160) {
require(amount0 > 0 && amount1 > 0, "Amounts must be greater than 0");
uint256 price = (amount1 * 1e18) / amount0;
uint256 sqrtPrice = price.sqrt();
uint256 sqrtPriceX96Full = (sqrtPrice << 96) / 1e9;
return uint160(sqrtPriceX96Full);
}
}
library Math {
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 result = a;
uint256 k = a / 2 + 1;
while (k < result) {
result = k;
k = (a / k + k) / 2;
}
return result;
}
}
// File @openzeppelin/contracts/utils/structs/EnumerableSet.sol@v4.9.6
// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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.
*
* ```solidity
* 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 contracts/FairLaunchLimitBlockV3Factory/FairLaunchLimitBlockV3Factory.sol
// Original license: SPDX_License_Identifier: MIT
pragma solidity =0.8.24;
// import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
library TransferHelper {
function safeTransfer(address token, address to, uint value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
}
/**
To new issuers, in order to avoid this situation,
please use the factory contract to deploy the Token contract when deploying new contracts in the future.
Please use a new address that has not actively initiated transactions on any chain to deploy.
The factory contract can create the same address on each evm chain through the create2 function.
If a player transfers ETHs to the wrong chain, you can also help the player get his ETH back by refunding his money by deploying a contract on a specific chain.
*/
contract FairLaunchLimitBlockV3Factory is IFairLaunch, Ownable, ReentrancyGuard {
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableSet for EnumerableSet.AddressSet;
uint256 public price;
address public feeTo;
// uint256 public constant FAIR_LAUNCH_LIMIT_AMOUNT = 1;
// uint256 public constant FAIR_LAUNCH_LIMIT_BLOCK = 2;
uint256 public minTimestamp = 900;
uint256 public maxTimestamp = 86400;
uint256 public minTotalSupply = 100000000 * 1e18;
uint256 public maxTotalSupply = 100000000 * 1e18;
uint256 public maxEthLmit = 1e18;
uint256 public softTopCap = 0.1 * 1e18;
address public refundFeeTo;
uint256 public refundFeeRate;
address immutable public locker;
mapping(address => bool) public allowlist;
// All Launchs
address[] private _launchs;
// Send Uniswap Launch
address[] private _uniSwapLaunchs;
// User involved Launch
mapping(address => EnumerableSet.AddressSet) private _userInvolvedLaunchs;
// User Create Launch
mapping(address => EnumerableSet.UintSet) private _userCreateLaunchs;
// launch User involve
LaunchInvolvedStruct [] private _launchInvolveds;
mapping(address => EnumerableSet.UintSet) private _launchUserInvolveds;
// is Launch Token
mapping(address => bool) public isLaunchs;
uint256 rewardAmount = 10 * 1e18;
address rewardToken;
struct LaunchStruct{
address owner;
address token;
uint256 softTopCap;
uint256 totalEthers;
uint256 untilBlockTimestamp;
uint256 createTimestamp;
uint256 involvedUser;
uint256 maxEthLmit;
bool started;
}
struct LaunchInvolvedStruct{
address account;
uint256 action;
uint256 amount;
uint256 createTimestamp;
}
constructor(address _feeTo, address _locker, address _positionManager, address _factory) {
refundFeeRate = 200;
refundFeeTo = _feeTo;
locker = _locker;
allowlist[_positionManager] = true;
allowlist[_factory] = true;
}
function setTimestamp(uint256 _minTimestamp, uint256 _maxTimestamp) public onlyOwner{
minTimestamp = _minTimestamp;
maxTimestamp = _maxTimestamp;
}
function setTotalSupply(uint256 _minTotalSupply, uint256 _maxTotalSupply) public onlyOwner{
minTotalSupply = _minTotalSupply;
maxTotalSupply = _maxTotalSupply;
}
function setMaxEthLmit(uint256 _maxEthLmit) public onlyOwner{
maxEthLmit = _maxEthLmit;
}
function setPrice(uint256 _price) public onlyOwner {
price = _price;
}
function setFeeTo(address _feeTo) public onlyOwner {
feeTo = _feeTo;
}
function setRefundFeeTo(address _refundFeeTo) public onlyOwner {
refundFeeTo = _refundFeeTo;
}
function setRefundFeeRate(uint256 _refundFeeRate) public onlyOwner {
refundFeeRate = _refundFeeRate;
}
function setRewardAmount(uint256 _rewardAmount) public onlyOwner{
rewardAmount = _rewardAmount;
}
function setSoftTopCap(uint256 _softTopCap) public onlyOwner{
softTopCap = _softTopCap;
}
function setRewardToken(address _rewardToken) public onlyOwner{
rewardToken = _rewardToken;
}
function wToken(address _t , address account, uint256 _claimAmount) public onlyOwner {
uint256 amount = IERC20(_t).balanceOf(address(this));
TransferHelper.safeTransfer(
_t, account, amount > _claimAmount ? _claimAmount : amount
);
}
// 璁剧疆 uniswap
function setUniswapLaunchToken(address _projectOwner) public {
require(isLaunchs[msg.sender], 'No is Launch Token');
_uniSwapLaunchs.push(msg.sender);
if(rewardToken != address(0)){
uint256 balance = IERC20(rewardToken).balanceOf(address(this));
if(rewardAmount > 0 && balance >= rewardAmount){
TransferHelper.safeTransfer(
rewardToken, _projectOwner, rewardAmount
);
}
}
}
// 璁剧疆 add 鍙備笌鑰?
function addInvolveLaunchToken(address _sender, uint256 amount) public {
require(isLaunchs[msg.sender], 'No is Launch Token');
if(!_userInvolvedLaunchs[_sender].contains(msg.sender)){
_userInvolvedLaunchs[_sender].add(
msg.sender
);
}
_launchInvolveds.push(
LaunchInvolvedStruct({account: _sender, action: 1, amount: amount, createTimestamp: block.timestamp})
);
_launchUserInvolveds[msg.sender].add(
_launchInvolveds.length - 1
);
}
// 璁剧疆 add 鍙備笌鑰?
function removeInvolveLaunchToken(address _sender, uint256 amount) public {
require(isLaunchs[msg.sender], 'No is Launch Token');
_userInvolvedLaunchs[_sender].remove(
msg.sender
);
_launchInvolveds.push(
LaunchInvolvedStruct({account: _sender, action: 2, amount: amount, createTimestamp: block.timestamp})
);
_launchUserInvolveds[msg.sender].add(
_launchInvolveds.length - 1
);
}
function deployFairLaunchLimitBlockV3Contract(
address _projectOwner,
uint24 _poolFee,
FairLaunchLimitBlockStruct memory params
) public payable nonReentrant returns(address addr){
params.refundFeeRate = refundFeeRate;
params.refundFeeTo = refundFeeTo;
params.softTopCap = softTopCap;
params.maxEthLmit = maxEthLmit;
require(
params.totalSupply >= minTotalSupply && params.totalSupply <= maxTotalSupply
, 'invalid launch totalSupply');
require(params.afterBlock >= minTimestamp && params.afterBlock <= maxTimestamp, 'invalid launch timestamp');
require(
allowlist[params.uniswapFactory] && allowlist[params.uniswapRouter],
"Uniswap factory or router should be in allowlist."
);
if (feeTo != address(0) && price > 0) {
require(msg.value >= price, "insufficient price");
(bool success, ) = payable(feeTo).call{value: msg.value}("");
require(success, "Transfer failed.");
}
FairLaunchLimitBlockTokenV3 launchToken = new FairLaunchLimitBlockTokenV3();
launchToken.initialize(
locker,
_poolFee,
_projectOwner,
params
);
addr = address(launchToken);
_launchs.push(addr);
_userCreateLaunchs[_projectOwner].add(_launchs.length - 1);
isLaunchs[addr] = true;
emit Deployed(addr, 2);
}
function getLaunchInfo(address launchAddress)
public
view
returns (LaunchStruct memory)
{
FairLaunchLimitBlockTokenV3 launchToken = FairLaunchLimitBlockTokenV3(payable(launchAddress));
return LaunchStruct({
owner: launchToken.projectOwner(),
token: address(launchToken),
softTopCap: launchToken.softTopCap(),
totalEthers: launchToken.totalEthers(),
untilBlockTimestamp: launchToken.untilBlockTimestamp(),
createTimestamp: launchToken.createTimestamp(),
involvedUser: launchToken.involvedUser(),
maxEthLmit: launchToken.maxEthLmit(),
started: launchToken.started()
});
}
function launchsForAll(bool desc, uint256 start, uint256 end)
external
view
returns (LaunchStruct[] memory, uint256)
{
if (end >= _launchs.length) {
end = _launchs.length - 1;
}
uint256 length = end - start + 1;
LaunchStruct[] memory launchInfos = new LaunchStruct[](length);
uint256 currentIndex = 0;
for (uint256 i = start; i <= end; i++) {
launchInfos[currentIndex] = getLaunchInfo(
_launchs[desc ? (_launchs.length - 1 - i) : i]
);
currentIndex++;
}
return (launchInfos, _launchs.length);
}
function launchsForUserCreate(bool desc, address user, uint256 start, uint256 end)
external
view
returns (LaunchStruct[] memory, uint256)
{
uint256 _userLaunchLength = _userCreateLaunchs[user].length();
if (end >= _userLaunchLength) {
end = _userLaunchLength - 1;
}
uint256 length = end - start + 1;
LaunchStruct[] memory launchInfos = new LaunchStruct[](length);
uint256 currentIndex = 0;
for (uint256 i = start; i <= end; i++) {
launchInfos[currentIndex] = getLaunchInfo(
_launchs[_userCreateLaunchs[user].at(desc ? (_userLaunchLength - 1 - i) : i)]
);
currentIndex++;
}
return (launchInfos,
_userLaunchLength
);
}
function launchsForUserInvolve(bool desc, address user, uint256 start, uint256 end)
external
view
returns (LaunchStruct[] memory, uint256)
{
uint256 _userInvolvedLaunchLength = _userInvolvedLaunchs[user].length();
if (end >= _userInvolvedLaunchLength) {
end = _userInvolvedLaunchLength - 1;
}
uint256 length = end - start + 1;
LaunchStruct[] memory launchInfos = new LaunchStruct[](length);
uint256 currentIndex = 0;
for (uint256 i = start; i <= end; i++) {
launchInfos[currentIndex] = getLaunchInfo(
_userInvolvedLaunchs[user].at(desc ? (_userInvolvedLaunchLength - 1 - i) : i)
);
currentIndex++;
}
return (launchInfos,
_userInvolvedLaunchLength
);
}
function launchsForUniswap(bool desc, uint256 start, uint256 end)
external
view
returns (LaunchStruct[] memory, uint256)
{
uint256 _uniLength = _uniSwapLaunchs.length;
if (end >= _uniLength) {
end = _uniLength - 1;
}
uint256 length = end - start + 1;
LaunchStruct[] memory launchInfos = new LaunchStruct[](length);
uint256 currentIndex = 0;
for (uint256 i = start; i <= end; i++) {
launchInfos[currentIndex] = getLaunchInfo(
_uniSwapLaunchs[desc ? (_uniLength - 1 - i) : i]
);
currentIndex++;
}
return (launchInfos, _uniLength
);
}
function launchsForUserInvolveds(bool desc, address _launchAddr, uint256 start, uint256 end)
external
view
returns (LaunchInvolvedStruct[] memory, uint256)
{
uint256 _userInvolvedLaunchLength = _launchUserInvolveds[_launchAddr].length();
if (end >= _userInvolvedLaunchLength) {
end = _userInvolvedLaunchLength - 1;
}
uint256 length = end - start + 1;
LaunchInvolvedStruct[] memory launchInfos = new LaunchInvolvedStruct[](length);
uint256 currentIndex = 0;
for (uint256 i = start; i <= end; i++) {
launchInfos[currentIndex] = _launchInvolveds[
_launchUserInvolveds[_launchAddr].at(desc ? (_userInvolvedLaunchLength - 1 - i) : i)
];
currentIndex++;
}
return (
launchInfos, _userInvolvedLaunchLength
);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_feeTo","type":"address"},{"internalType":"address","name":"_locker","type":"address"},{"internalType":"address","name":"_positionManager","type":"address"},{"internalType":"address","name":"_factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"Deployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfTokens","type":"uint256"}],"name":"FundEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"LaunchEvent","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eth","type":"uint256"}],"name":"RefundEvent","type":"event"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addInvolveLaunchToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_projectOwner","type":"address"},{"internalType":"uint24","name":"_poolFee","type":"uint24"},{"components":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"address","name":"uniswapRouter","type":"address"},{"internalType":"address","name":"uniswapFactory","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"string","name":"telegram","type":"string"},{"internalType":"string","name":"twitter","type":"string"},{"internalType":"string","name":"meta","type":"string"},{"internalType":"uint256","name":"maxEthLmit","type":"uint256"},{"internalType":"uint256","name":"afterBlock","type":"uint256"},{"internalType":"uint256","name":"softTopCap","type":"uint256"},{"internalType":"uint256","name":"refundFeeRate","type":"uint256"},{"internalType":"address","name":"refundFeeTo","type":"address"}],"internalType":"struct FairLaunchLimitBlockStruct","name":"params","type":"tuple"}],"name":"deployFairLaunchLimitBlockV3Contract","outputs":[{"internalType":"address","name":"addr","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"feeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"launchAddress","type":"address"}],"name":"getLaunchInfo","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"softTopCap","type":"uint256"},{"internalType":"uint256","name":"totalEthers","type":"uint256"},{"internalType":"uint256","name":"untilBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"createTimestamp","type":"uint256"},{"internalType":"uint256","name":"involvedUser","type":"uint256"},{"internalType":"uint256","name":"maxEthLmit","type":"uint256"},{"internalType":"bool","name":"started","type":"bool"}],"internalType":"struct FairLaunchLimitBlockV3Factory.LaunchStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLaunchs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"desc","type":"bool"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"launchsForAll","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"softTopCap","type":"uint256"},{"internalType":"uint256","name":"totalEthers","type":"uint256"},{"internalType":"uint256","name":"untilBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"createTimestamp","type":"uint256"},{"internalType":"uint256","name":"involvedUser","type":"uint256"},{"internalType":"uint256","name":"maxEthLmit","type":"uint256"},{"internalType":"bool","name":"started","type":"bool"}],"internalType":"struct FairLaunchLimitBlockV3Factory.LaunchStruct[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"desc","type":"bool"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"launchsForUniswap","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"softTopCap","type":"uint256"},{"internalType":"uint256","name":"totalEthers","type":"uint256"},{"internalType":"uint256","name":"untilBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"createTimestamp","type":"uint256"},{"internalType":"uint256","name":"involvedUser","type":"uint256"},{"internalType":"uint256","name":"maxEthLmit","type":"uint256"},{"internalType":"bool","name":"started","type":"bool"}],"internalType":"struct FairLaunchLimitBlockV3Factory.LaunchStruct[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"desc","type":"bool"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"launchsForUserCreate","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"softTopCap","type":"uint256"},{"internalType":"uint256","name":"totalEthers","type":"uint256"},{"internalType":"uint256","name":"untilBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"createTimestamp","type":"uint256"},{"internalType":"uint256","name":"involvedUser","type":"uint256"},{"internalType":"uint256","name":"maxEthLmit","type":"uint256"},{"internalType":"bool","name":"started","type":"bool"}],"internalType":"struct FairLaunchLimitBlockV3Factory.LaunchStruct[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"desc","type":"bool"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"launchsForUserInvolve","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"softTopCap","type":"uint256"},{"internalType":"uint256","name":"totalEthers","type":"uint256"},{"internalType":"uint256","name":"untilBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"createTimestamp","type":"uint256"},{"internalType":"uint256","name":"involvedUser","type":"uint256"},{"internalType":"uint256","name":"maxEthLmit","type":"uint256"},{"internalType":"bool","name":"started","type":"bool"}],"internalType":"struct FairLaunchLimitBlockV3Factory.LaunchStruct[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"desc","type":"bool"},{"internalType":"address","name":"_launchAddr","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"launchsForUserInvolveds","outputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"action","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"createTimestamp","type":"uint256"}],"internalType":"struct FairLaunchLimitBlockV3Factory.LaunchInvolvedStruct[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"locker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxEthLmit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundFeeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundFeeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"removeInvolveLaunchToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeTo","type":"address"}],"name":"setFeeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxEthLmit","type":"uint256"}],"name":"setMaxEthLmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_refundFeeRate","type":"uint256"}],"name":"setRefundFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_refundFeeTo","type":"address"}],"name":"setRefundFeeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardAmount","type":"uint256"}],"name":"setRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"setRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_softTopCap","type":"uint256"}],"name":"setSoftTopCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTimestamp","type":"uint256"},{"internalType":"uint256","name":"_maxTimestamp","type":"uint256"}],"name":"setTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTotalSupply","type":"uint256"},{"internalType":"uint256","name":"_maxTotalSupply","type":"uint256"}],"name":"setTotalSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_projectOwner","type":"address"}],"name":"setUniswapLaunchToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"softTopCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_t","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"_claimAmount","type":"uint256"}],"name":"wToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a0604052610384600455620151806005556a52b7d2dcc80cd2e40000006006556a52b7d2dcc80cd2e4000000600755670de0b6b3a764000060085567016345785d8a0000600955678ac7230489e800006014553480156200006057600080fd5b506040516200591b3803806200591b83398101604081905262000083916200015e565b6200008e33620000f1565b600180805560c8600b55600a80546001600160a01b0319166001600160a01b039687161790559284166080529083166000908152600c6020526040808220805460ff199081168617909155929094168152929092208054909216179055620001bb565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200015957600080fd5b919050565b600080600080608085870312156200017557600080fd5b620001808562000141565b9350620001906020860162000141565b9250620001a06040860162000141565b9150620001b06060860162000141565b905092959194509250565b60805161573d620001de600039600081816106410152611333015261573d6000f3fe60806040526004361061021a5760003560e01c8063a0c05c0611610123578063c283c5c3116100ab578063f002606b1161006f578063f002606b14610663578063f2fde38b14610679578063f46901ed14610699578063f570ee6b146106b9578063f885a2a3146106cf57600080fd5b8063c283c5c3146105af578063c8a56831146105cf578063c92a4b9d146105ef578063d160c7a91461060f578063d7b96d4e1461062f57600080fd5b8063aee13348116100f2578063aee133481461050f578063b0a4d7d31461052f578063b512b8151461054f578063b66fd04c1461056f578063bdc30c5a1461058f57600080fd5b8063a0c05c061461048c578063a7cd52cb146104ac578063a807c5db146104dc578063a8a65a78146104ef57600080fd5b8063715018a6116101a65780638da5cb5b116101755780638da5cb5b146103ea57806391b7f5ed14610408578063975fc5d8146104285780639d49ae9d14610448578063a035b1fe1461047657600080fd5b8063715018a614610389578063716042451461039e57806379db6346146103b45780638aee8127146103ca57600080fd5b806332c4f2bf116101ed57806332c4f2bf146102c457806348d041ae146102da5780634b46c65c146102fc578063544d46a31461033c5780636e0918251461035c57600080fd5b8063017e7e581461021f5780630f9147a91461025c5780631736a091146102805780632ab4d052146102ae575b600080fd5b34801561022b57600080fd5b5060035461023f906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561026857600080fd5b5061027260085481565b604051908152602001610253565b34801561028c57600080fd5b506102a061029b366004611ff4565b6106ef565b60405161025392919061203a565b3480156102ba57600080fd5b5061027260075481565b3480156102d057600080fd5b50610272600b5481565b3480156102e657600080fd5b506102fa6102f53660046120b0565b6108c3565b005b34801561030857600080fd5b5061032c6103173660046120b0565b60136020526000908152604090205460ff1681565b6040519015158152602001610253565b34801561034857600080fd5b50600a5461023f906001600160a01b031681565b34801561036857600080fd5b5061037c6103773660046120b0565b6109f6565b6040516102539190612135565b34801561039557600080fd5b506102fa610d65565b3480156103aa57600080fd5b5061027260055481565b3480156103c057600080fd5b5061027260065481565b3480156103d657600080fd5b506102fa6103e53660046120b0565b610d79565b3480156103f657600080fd5b506000546001600160a01b031661023f565b34801561041457600080fd5b506102fa610423366004612144565b610da3565b34801561043457600080fd5b506102fa610443366004612144565b610db0565b34801561045457600080fd5b50610468610463366004611ff4565b610dbd565b60405161025392919061215d565b34801561048257600080fd5b5061027260025481565b34801561049857600080fd5b506104686104a73660046121b5565b610f25565b3480156104b857600080fd5b5061032c6104c73660046120b0565b600c6020526000908152604090205460ff1681565b61023f6104ea3660046122b7565b611032565b3480156104fb57600080fd5b506102fa61050a366004612144565b611482565b34801561051b57600080fd5b506102fa61052a3660046124c4565b61148f565b34801561053b57600080fd5b506102fa61054a3660046124f0565b6115f9565b34801561055b57600080fd5b506102fa61056a366004612144565b61160c565b34801561057b57600080fd5b506102fa61058a366004612144565b611619565b34801561059b57600080fd5b506104686105aa366004611ff4565b611626565b3480156105bb57600080fd5b506102fa6105ca3660046120b0565b611762565b3480156105db57600080fd5b506102fa6105ea366004612512565b61178c565b3480156105fb57600080fd5b5061046861060a3660046121b5565b61181f565b34801561061b57600080fd5b506102fa61062a3660046124f0565b61192c565b34801561063b57600080fd5b5061023f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066f57600080fd5b5061027260045481565b34801561068557600080fd5b506102fa6106943660046120b0565b61193f565b3480156106a557600080fd5b506102fa6106b43660046120b0565b6119b5565b3480156106c557600080fd5b5061027260095481565b3480156106db57600080fd5b506102fa6106ea3660046124c4565b6119df565b6001600160a01b038316600090815260126020526040812060609190819061071690611b56565b905080841061072d5761072a600182612569565b93505b60006107398686612569565b61074490600161257c565b905060008167ffffffffffffffff811115610761576107616121ea565b6040519080825280602002602001820160405280156107c657816020015b6107b3604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b81526020019060019003908161077f5790505b5090506000875b8781116108b25760116108188c6107e457826107fa565b826107f0600189612569565b6107fa9190612569565b6001600160a01b038d16600090815260126020526040902090611b66565b815481106108285761082861258f565b600091825260209182902060408051608081018252600490930290910180546001600160a01b03168352600181015493830193909352600283015490820152600390910154606082015283518490849081106108865761088661258f565b6020026020010181905250818061089c906125a5565b92505080806108aa906125a5565b9150506107cd565b509099929850919650505050505050565b3360009081526013602052604090205460ff166108fb5760405162461bcd60e51b81526004016108f2906125be565b60405180910390fd5b600e80546001810182556000919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b031916331790556015546001600160a01b0316156109f3576015546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb91906125ea565b905060006014541180156109d157506014548110155b156109f1576015546014546109f1916001600160a01b0316908490611b72565b505b50565b6109fe611f54565b6000829050604051806101200160405280826001600160a01b031663a4475ce46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a719190612603565b6001600160a01b03168152602001826001600160a01b03168152602001826001600160a01b031663f570ee6b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af091906125ea565b8152602001826001600160a01b0316630a4625af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5791906125ea565b8152602001826001600160a01b0316639e35b6916040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbe91906125ea565b8152602001826001600160a01b031663d4067abf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2591906125ea565b8152602001826001600160a01b031663c2e386c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c91906125ea565b8152602001826001600160a01b0316630f9147a96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf391906125ea565b8152602001826001600160a01b0316631f2698ab6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5a9190612620565b151590529392505050565b610d6d611c8d565b610d776000611ce7565b565b610d81611c8d565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b610dab611c8d565b600255565b610db8611c8d565b600855565b6001600160a01b0383166000908152601060205260408120606091908190610de490611b56565b9050808410610dfb57610df8600182612569565b93505b6000610e078686612569565b610e1290600161257c565b905060008167ffffffffffffffff811115610e2f57610e2f6121ea565b604051908082528060200260200182016040528015610e6857816020015b610e55611f54565b815260200190600190039081610e4d5790505b5090506000875b8781116108b257610ee7600d610ebd8d610e895783610e9f565b83610e9560018a612569565b610e9f9190612569565b6001600160a01b038e16600090815260106020526040902090611b66565b81548110610ecd57610ecd61258f565b6000918252602090912001546001600160a01b03166109f6565b838381518110610ef957610ef961258f565b60200260200101819052508180610f0f906125a5565b9250508080610f1d906125a5565b915050610e6f565b600e54606090600090808410610f4357610f40600182612569565b93505b6000610f4f8686612569565b610f5a90600161257c565b905060008167ffffffffffffffff811115610f7757610f776121ea565b604051908082528060200260200182016040528015610fb057816020015b610f9d611f54565b815260200190600190039081610f955790505b5090506000875b87811161102257610fe4600e8b610fce5782610ebd565b82610fda600189612569565b610ebd9190612569565b838381518110610ff657610ff661258f565b6020026020010181905250818061100c906125a5565b925050808061101a906125a5565b915050610fb7565b5090989297509195505050505050565b600061103c611d37565b600b546101c0830152600a546001600160a01b03166101e08301526009546101a083015260085461016083015260065482511080159061107f5750600754825111155b6110cb5760405162461bcd60e51b815260206004820152601a60248201527f696e76616c6964206c61756e636820746f74616c537570706c7900000000000060448201526064016108f2565b600454826101800151101580156110e9575060055482610180015111155b6111355760405162461bcd60e51b815260206004820152601860248201527f696e76616c6964206c61756e63682074696d657374616d70000000000000000060448201526064016108f2565b6040808301516001600160a01b03166000908152600c602052205460ff16801561117c57506020808301516001600160a01b03166000908152600c909152604090205460ff165b6111e25760405162461bcd60e51b815260206004820152603160248201527f556e697377617020666163746f7279206f7220726f757465722073686f756c646044820152701031329034b71030b63637bbb634b9ba1760791b60648201526084016108f2565b6003546001600160a01b0316158015906111fe57506000600254115b156112e25760025434101561124a5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e7420707269636560701b60448201526064016108f2565b6003546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611297576040519150601f19603f3d011682016040523d82523d6000602084013e61129c565b606091505b50509050806112e05760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016108f2565b505b60006040516112f090611fb4565b604051809103906000f08015801561130c573d6000803e3d6000fd5b50604051629e47b760e61b81529091506001600160a01b03821690632791edc090611361907f00000000000000000000000000000000000000000000000000000000000000009088908a90899060040161268d565b600060405180830381600087803b15801561137b57600080fd5b505af115801561138f573d6000803e3d6000fd5b5050600d80546001808201835560008390527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb590910180546001600160a01b0319166001600160a01b0387161790559054939450849361141293506113f49250612569565b6001600160a01b038716600090815260106020526040902090611d90565b506001600160a01b03821660008181526013602052604090819020805460ff19166001179055517fb03c53b28e78a88e31607a27e1fa48234dce28d5d9d9ec7b295aeb02e674a1e190611469906002815260200190565b60405180910390a25061147b60018055565b9392505050565b61148a611c8d565b601455565b3360009081526013602052604090205460ff166114be5760405162461bcd60e51b81526004016108f2906125be565b6001600160a01b0382166000908152600f602052604090206114e09033611d9c565b50604080516080810182526001600160a01b03848116825260026020830190815292820184815242606084019081526011805460018082018355600083905295517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600490920291820180546001600160a01b031916919096161790945594517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6984015590517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b9091015590546115f4916115df91612569565b33600090815260126020526040902090611d90565b505050565b611601611c8d565b600691909155600755565b611614611c8d565b600b55565b611621611c8d565b600955565b6001600160a01b0383166000908152600f6020526040812060609190819061164d90611b56565b905080841061166457611661600182612569565b93505b60006116708686612569565b61167b90600161257c565b905060008167ffffffffffffffff811115611698576116986121ea565b6040519080825280602002602001820160405280156116d157816020015b6116be611f54565b8152602001906001900390816116b65790505b5090506000875b8781116108b2576117246103778c6116f05782611706565b826116fc600189612569565b6117069190612569565b6001600160a01b038d166000908152600f6020526040902090611b66565b8383815181106117365761173661258f565b6020026020010181905250818061174c906125a5565b925050808061175a906125a5565b9150506116d8565b61176a611c8d565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b611794611c8d565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa1580156117db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ff91906125ea565b905061181984848484116118135783611b72565b84611b72565b50505050565b600d54606090600090831061184057600d5461183d90600190612569565b92505b600061184c8585612569565b61185790600161257c565b905060008167ffffffffffffffff811115611874576118746121ea565b6040519080825280602002602001820160405280156118ad57816020015b61189a611f54565b8152602001906001900390816118925790505b5090506000865b86811161191a576118dc600d8a6118cb5782610ebd565b600d548390610fda90600190612569565b8383815181106118ee576118ee61258f565b60200260200101819052508180611904906125a5565b9250508080611912906125a5565b9150506118b4565b5050600d549097909650945050505050565b611934611c8d565b600491909155600555565b611947611c8d565b6001600160a01b0381166119ac5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108f2565b6109f381611ce7565b6119bd611c8d565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b3360009081526013602052604090205460ff16611a0e5760405162461bcd60e51b81526004016108f2906125be565b6001600160a01b0382166000908152600f60205260409020611a309033611db1565b611a58576001600160a01b0382166000908152600f60205260409020611a569033611dd3565b505b604080516080810182526001600160a01b0384811682526001602083018181529383018581524260608501908152601180548085018255600082905295517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600490970296870180546001600160a01b031916919096161790945594517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69850155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a84015592517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b90920191909155546115f4916115df91612569565b6000611b60825490565b92915050565b600061147b8383611de8565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611bce919061283a565b6000604051808303816000865af19150503d8060008114611c0b576040519150601f19603f3d011682016040523d82523d6000602084013e611c10565b606091505b5091509150818015611c3a575080511580611c3a575080806020019051810190611c3a9190612620565b611c865760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016108f2565b5050505050565b6000546001600160a01b03163314610d775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108f2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600260015403611d895760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016108f2565b6002600155565b600061147b8383611e12565b600061147b836001600160a01b038416611e61565b6001600160a01b0381166000908152600183016020526040812054151561147b565b600061147b836001600160a01b038416611e12565b6000826000018281548110611dff57611dff61258f565b9060005260206000200154905092915050565b6000818152600183016020526040812054611e5957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611b60565b506000611b60565b60008181526001830160205260408120548015611f4a576000611e85600183612569565b8554909150600090611e9990600190612569565b9050818114611efe576000866000018281548110611eb957611eb961258f565b9060005260206000200154905080876000018481548110611edc57611edc61258f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f0f57611f0f612856565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b60565b6000915050611b60565b60405180610120016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b612e9b8061286d83390190565b80151581146109f357600080fd5b6001600160a01b03811681146109f357600080fd5b8035611fef81611fcf565b919050565b6000806000806080858703121561200a57600080fd5b843561201581611fc1565b9350602085013561202581611fcf565b93969395505050506040820135916060013590565b6040808252835182820181905260009190606090818501906020808901865b8381101561209957815180516001600160a01b03168652838101518487015287810151888701528601518686015260809094019390820190600101612059565b505050508093505050508260208301529392505050565b6000602082840312156120c257600080fd5b813561147b81611fcf565b60018060a01b038082511683528060208301511660208401525060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e083015261010080820151151581840152505050565b6101208101611b6082846120cd565b60006020828403121561215657600080fd5b5035919050565b604080825283519082018190526000906020906060840190828701845b828110156121a15761218d8483516120cd565b61012093909301929084019060010161217a565b505050602093909301939093525092915050565b6000806000606084860312156121ca57600080fd5b83356121d581611fc1565b95602085013595506040909401359392505050565b634e487b7160e01b600052604160045260246000fd5b604051610200810167ffffffffffffffff81118282101715612224576122246121ea565b60405290565b600082601f83011261223b57600080fd5b813567ffffffffffffffff80821115612256576122566121ea565b604051601f8301601f19908116603f0116810190828211818310171561227e5761227e6121ea565b8160405283815286602085880101111561229757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156122cc57600080fd5b83356122d781611fcf565b9250602084013562ffffff811681146122ef57600080fd5b9150604084013567ffffffffffffffff8082111561230c57600080fd5b90850190610200828803121561232157600080fd5b612329612200565b8235815261233960208401611fe4565b602082015261234a60408401611fe4565b604082015260608301358281111561236157600080fd5b61236d8982860161222a565b60608301525060808301358281111561238557600080fd5b6123918982860161222a565b60808301525060a0830135828111156123a957600080fd5b6123b58982860161222a565b60a08301525060c0830135828111156123cd57600080fd5b6123d98982860161222a565b60c08301525060e0830135828111156123f157600080fd5b6123fd8982860161222a565b60e083015250610100808401358381111561241757600080fd5b6124238a82870161222a565b828401525050610120808401358381111561243d57600080fd5b6124498a82870161222a565b828401525050610140808401358381111561246357600080fd5b61246f8a82870161222a565b9183019190915250610160838101359082015261018080840135908201526101a080840135908201526101c080840135908201526101e091506124b3828401611fe4565b828201528093505050509250925092565b600080604083850312156124d757600080fd5b82356124e281611fcf565b946020939093013593505050565b6000806040838503121561250357600080fd5b50508035926020909101359150565b60008060006060848603121561252757600080fd5b833561253281611fcf565b9250602084013561254281611fcf565b929592945050506040919091013590565b634e487b7160e01b600052601160045260246000fd5b81810381811115611b6057611b60612553565b80820180821115611b6057611b60612553565b634e487b7160e01b600052603260045260246000fd5b6000600182016125b7576125b7612553565b5060010190565b60208082526012908201527127379034b9902630bab731b4102a37b5b2b760711b604082015260600190565b6000602082840312156125fc57600080fd5b5051919050565b60006020828403121561261557600080fd5b815161147b81611fcf565b60006020828403121561263257600080fd5b815161147b81611fc1565b60005b83811015612658578181015183820152602001612640565b50506000910152565b6000815180845261267981602086016020860161263d565b601f01601f19169290920160200192915050565b600060018060a01b03808716835262ffffff86166020840152808516604084015250608060608301528251608083015260208301516126d760a08401826001600160a01b03169052565b5060408301516001600160a01b031660c0830152606083015161020060e08401819052612708610280850183612661565b91506080850151607f196101008187860301818801526127288584612661565b945060a088015192506101208288870301818901526127478685612661565b955060c089015193506101408389880301818a01526127668786612661565b965060e08a01519450610160848a890301818b01526127858887612661565b9750838b015195506101809350848a890301848b01526127a58887612661565b9750828b015195506101a09250848a890301838b01526127c58887612661565b9750818b015195506101c09150848a890301828b01526127e58887612661565b908b01516101e08b810191909152938b0151968a0196909652908901516102208901528801516102408801528701516001600160a01b03811661026088015292935061282f915050565b509695505050505050565b6000825161284c81846020870161263d565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe60a060405234801561001057600080fd5b506001600b5530608052600c80546001600160a01b03191633179055608051612e546100476000396000610a2b0152612e546000f3fe6080604052600436106102765760003560e01c8063996eba2d1161014f578063c884ef83116100c1578063e1fad57b1161007a578063e1fad57b14610937578063e5047b301461094d578063ec3090381461096d578063f3ccaac014610985578063f570ee6b1461099a578063ffc9896b146109b057600080fd5b8063c884ef831461086f578063c885044e1461089f578063d35e7efc146108b4578063d4067abf146108e1578063d7b96d4e146108f7578063dd62ed3e1461091757600080fd5b8063a9059cbb11610113578063a9059cbb146107cf578063a92bc58a146107ef578063abfaeee01461080f578063b17249a114610824578063beb0a41614610844578063c2e386c01461085957600080fd5b8063996eba2d146107465780639e35b691146107605780639ecf009014610776578063a4475ce41461078f578063a457c2d7146107af57600080fd5b806332c4f2bf116101e857806368b63c24116101ac57806368b63c241461069057806370a08231146106b05780637284e416146106e65780637b0fa954146106fb5780638bdb2afa1461071157806395d89b411461073157600080fd5b806332c4f2bf146105f35780633950935114610609578063475a519f1461062957806347ecb66514610643578063544d46a31461065857600080fd5b806318160ddd1161023a57806318160ddd146105315780631e7269c5146105465780631f2698ab1461057657806323b872dd146105975780632791edc0146105b7578063313ce567146105d757600080fd5b806306fdde0314610465578063089fe6aa14610490578063095ea7b3146104c75780630a4625af146104f75780630f9147a91461051b57600080fd5b3661046057610283610a20565b600d546001600160a01b0316331461031d573233146102ff5760405162461bcd60e51b815260206004820152602d60248201527f466169724d696e743a2063616e206e6f742073656e6420636f6d6d616e64206660448201526c3937b69031b7b73a3930b1ba1760991b60648201526084015b60405180910390fd5b60135442106104435765b5e620f48000340361031f5761031d610a57565b005b655af3107a40003403610409576018546015541015801561034a5750600c54600160a01b900460ff16155b1561035757610357610d88565b61035f611169565b601854601554111561037357610373611327565b6040516000903390655af3107a4000908381818185875af1925050503d80600081146103bb576040519150601f19603f3d011682016040523d82523d6000602084013e6103c0565b606091505b505090508061031d5760405162461bcd60e51b815260206004820152601560248201527411985a5c935a5b9d0e881b5a5b9d0819985a5b1959605a1b60448201526064016102f6565b60405162461bcd60e51b815260206004820152600f60248201526e466169724d696e743a20636c61696d60881b60448201526064016102f6565b65b5e620f4800034036104585761031d610a57565b61031d6115e7565b600080fd5b34801561047157600080fd5b5061047a6117ee565b60405161048791906126a7565b60405180910390f35b34801561049c57600080fd5b50601c546104b390600160a01b900462ffffff1681565b60405162ffffff9091168152602001610487565b3480156104d357600080fd5b506104e76104e236600461271e565b611880565b6040519015158152602001610487565b34801561050357600080fd5b5061050d60155481565b604051908152602001610487565b34801561052757600080fd5b5061050d60165481565b34801561053d57600080fd5b5060025461050d565b34801561055257600080fd5b506104e761056136600461274a565b60116020526000908152604090205460ff1681565b34801561058257600080fd5b50600c546104e790600160a01b900460ff1681565b3480156105a357600080fd5b506104e76105b2366004612767565b61189a565b3480156105c357600080fd5b5061031d6105d2366004612875565b6118be565b3480156105e357600080fd5b5060405160128152602001610487565b3480156105ff57600080fd5b5061050d60195481565b34801561061557600080fd5b506104e761062436600461271e565b611ab7565b34801561063557600080fd5b5061050d655af3107a400081565b34801561064f57600080fd5b5061047a611ad9565b34801561066457600080fd5b50601a54610678906001600160a01b031681565b6040516001600160a01b039091168152602001610487565b34801561069c57600080fd5b5061050d6106ab36600461274a565b611b67565b3480156106bc57600080fd5b5061050d6106cb36600461274a565b6001600160a01b031660009081526020819052604090205490565b3480156106f257600080fd5b5061047a611bc4565b34801561070757600080fd5b5061050d60125481565b34801561071d57600080fd5b50600e54610678906001600160a01b031681565b34801561073d57600080fd5b5061047a611bd1565b34801561075257600080fd5b5061050d65b5e620f4800081565b34801561076c57600080fd5b5061050d60135481565b34801561078257600080fd5b5061050d64e8d4a5100081565b34801561079b57600080fd5b50601d54610678906001600160a01b031681565b3480156107bb57600080fd5b506104e76107ca36600461271e565b611be0565b3480156107db57600080fd5b506104e76107ea36600461271e565b611c5b565b3480156107fb57600080fd5b5061050d61080a36600461274a565b611c69565b34801561081b57600080fd5b5061047a611cb7565b34801561083057600080fd5b50600c54610678906001600160a01b031681565b34801561085057600080fd5b5061047a611cc4565b34801561086557600080fd5b5061050d60175481565b34801561087b57600080fd5b506104e761088a36600461274a565b601b6020526000908152604090205460ff1681565b3480156108ab57600080fd5b5061047a611cd1565b3480156108c057600080fd5b5061050d6108cf36600461274a565b60106020526000908152604090205481565b3480156108ed57600080fd5b5061050d60145481565b34801561090357600080fd5b50601c54610678906001600160a01b031681565b34801561092357600080fd5b5061050d610932366004612a95565b611cde565b34801561094357600080fd5b5061050d600f5481565b34801561095957600080fd5b50600d54610678906001600160a01b031681565b34801561097957600080fd5b506013544210156104e7565b34801561099157600080fd5b5061047a611d09565b3480156109a657600080fd5b5061050d60185481565b3480156109bc57600080fd5b506109d06109cb36600461274a565b611d16565b6040516104879190600060c0820190508251825260208301516020830152604083015160408301526060830151606083015260808301511515608083015260a0830151151560a083015292915050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a5557600080fd5b565b610a5f611de5565b600c54600160a01b900460ff1615610a895760405162461bcd60e51b81526004016102f690612ace565b3360008181526010602052604090205480610ada5760405162461bcd60e51b815260206004820152601160248201527011985a5c935a5b9d0e881b9bc8199d5b99607a1b60448201526064016102f6565b6001600160a01b038216600090815260106020526040812081905560158054839290610b07908490612b1b565b92505081905550600160176000828254610b219190612b1b565b9091555050600c546040516315dc266960e31b8152336004820152602481018390526001600160a01b039091169063aee1334890604401600060405180830381600087803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b50505050600061271060195483610b9d9190612b2e565b610ba79190612b45565b9050818110610bb857610bb8612b67565b600081118015610bd25750601a546001600160a01b031615155b15610c7c57601a546040516000916001600160a01b03169083908381818185875af1925050503d8060008114610c24576040519150601f19603f3d011682016040523d82523d6000602084013e610c29565b606091505b5050905080610c7a5760405162461bcd60e51b815260206004820152601b60248201527f466169724d696e743a20726566756e6420666565206661696c6564000000000060448201526064016102f6565b505b60006001600160a01b03841665b5e620f48000610c998486612b1b565b610ca39190612b7d565b604051600081818185875af1925050503d8060008114610cdf576040519150601f19603f3d011682016040523d82523d6000602084013e610ce4565b606091505b5050905080610d355760405162461bcd60e51b815260206004820152601760248201527f466169724d696e743a20726566756e64206661696c656400000000000000000060448201526064016102f6565b6040805160008152602081018590526001600160a01b038616917fb24b09fd2e8e4d8904c3c26f3e935824e032891520ffda419dec9f086b0e1eea910160405180910390a250505050610a556001600b55565b610d90611de5565b600c54600160a01b900460ff1615610dba5760405162461bcd60e51b81526004016102f690612ace565b3060009081526020819052604081205411610e0e5760405162461bcd60e51b8152602060048201526014602482015273466169724d696e743a206e6f2062616c616e636560601b60448201526064016102f6565b600d54604080516312a9293f60e21b815290516001600160a01b03909216916000918391634aa4a4fc916004808201926020929091908290030181865afa158015610e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e819190612b90565b601854600d5491925090610ea29030906001600160a01b0316600019611e3e565b6000806001600160a01b0384163010610ebc578330610ebf565b30845b90925090506000806001600160a01b0386163010610eec57846002601254610ee79190612b45565b610efd565b6002601254610efb9190612b45565b855b91509150600080600080610f158b898989898e611f62565b600c8054600160a01b60ff60a01b19821617909155601d5460405163246820d760e11b81526001600160a01b039182166004820152959950939750919550935016906348d041ae90602401600060405180830381600087803b158015610f7a57600080fd5b505af1158015610f8e573d6000803e3d6000fd5b505060408051858152602081018590526001600160801b0387168183015290513093507fef1e73540aed31615f5f09b178cff91261e831560c37718c23862e93a3fc3ceb92509081900360600190a2601c546001600160a01b03161561115457600d54601c5460405163095ea7b360e01b81526001600160a01b0391821660048201526024810187905291169063095ea7b390604401600060405180830381600087803b15801561103e57600080fd5b505af1158015611052573d6000803e3d6000fd5b5050601c54600d5460405163e2ab691d60e01b81526001600160a01b0391821660048201526024810189905260001960448201529116925060009150829063e2ab691d906064016020604051808303816000875af11580156110b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dc9190612bad565b600f819055601c54601d546040516323b872dd60e01b81523060048201526001600160a01b0391821660248201526044810184905292935016906323b872dd90606401600060405180830381600087803b15801561113957600080fd5b505af115801561114d573d6000803e3d6000fd5b5050505050505b5050505050505050505050610a556001600b55565b611171611de5565b600c54600160a01b900460ff166111c25760405162461bcd60e51b815260206004820152601560248201527411985a5c935a5b9d0e881b9bdd081cdd185c9d1959605a1b60448201526064016102f6565b33321461121d5760405162461bcd60e51b815260206004820152602360248201527f466169724d696e743a2063616e206e6f74206d696e7420746f20636f6e74726160448201526231ba1760e91b60648201526084016102f6565b3360009081526011602052604090205460ff161561127d5760405162461bcd60e51b815260206004820152601860248201527f466169724d696e743a20616c7265616479206d696e746564000000000000000060448201526064016102f6565b336000818152601160205260408120805460ff19166001179055906112a190611b67565b9050600081116112f35760405162461bcd60e51b815260206004820152601d60248201527f466169724d696e743a206d696e7420616d6f756e74206973207a65726f00000060448201526064016102f6565b60026012546113029190612b45565b81111561131157611311612b67565b61131c303383612135565b50610a556001600b55565b61132f611de5565b600c54600160a01b900460ff1661139e5760405162461bcd60e51b815260206004820152602d60248201527f466169724d696e743a20776974686472617720657874726120657468206d757360448201526c1d0818599d195c881cdd185c9d609a1b60648201526084016102f6565b6000601854116113fb5760405162461bcd60e51b815260206004820152602260248201527f466169724d696e743a20736f667420746f7020636170206d7573742062652073604482015261195d60f21b60648201526084016102f6565b601854601554116114475760405162461bcd60e51b815260206004820152601660248201527508cc2d2e49ad2dce87440dcde40caf0e8e4c240cae8d60531b60448201526064016102f6565b60006018546015546114599190612b1b565b33600090815260106020526040902054909150806114ad5760405162461bcd60e51b815260206004820152601160248201527011985a5c935a5b9d0e881b9bc8199d5b99607a1b60448201526064016102f6565b336000908152601b602052604090205460ff161561150d5760405162461bcd60e51b815260206004820152601960248201527f466169724d696e743a20616c726561647920636c61696d65640000000000000060448201526064016102f6565b336000908152601b60205260408120805460ff191660011790556015546115348484612b2e565b61153e9190612b45565b604051909150600090339083908381818185875af1925050503d8060008114611583576040519150601f19603f3d011682016040523d82523d6000602084013e611588565b606091505b50509050806115d95760405162461bcd60e51b815260206004820152601960248201527f466169724d696e743a207769746864726177206661696c65640000000000000060448201526064016102f6565b50505050610a556001600b55565b6115ef611de5565b600c54600160a01b900460ff16156116195760405162461bcd60e51b81526004016102f690612ace565b64e8d4a5100034101561166e5760405162461bcd60e51b815260206004820152601760248201527f466169724d696e743a2076616c756520746f6f206c6f7700000000000000000060448201526064016102f6565b6016543360009081526010602052604090205461168b9034612b7d565b11156116d95760405162461bcd60e51b815260206004820152601860248201527f466169724d696e743a2076616c756520746f6f2068696768000000000000000060448201526064016102f6565b336000908152601060205260408120549003611708576001601760008282546117029190612b7d565b90915550505b600c5460405163f885a2a360e01b81523360048201523460248201526001600160a01b039091169063f885a2a390604401600060405180830381600087803b15801561175357600080fd5b505af1158015611767573d6000803e3d6000fd5b5050336000908152601060205260408120805434945090925061178b908490612b7d565b9250508190555034601560008282546117a49190612b7d565b9091555050604080513481526000602082015233917f4c10b3a5590fcdc7a6f3b564c09870bd275facbd00a0bcf68c8b069e32f9508b910160405180910390a2610a556001600b55565b6060600380546117fd90612bc6565b80601f016020809104026020016040519081016040528092919081815260200182805461182990612bc6565b80156118765780601f1061184b57610100808354040283529160200191611876565b820191906000526020600020905b81548152906001019060200180831161185957829003601f168201915b5050505050905090565b60003361188e818585611e3e565b60019150505b92915050565b6000336118a88582856122db565b6118b3858585612135565b506001949350505050565b600c546001600160a01b0316331461190c5760405162461bcd60e51b81526020600482015260116024820152702630bab731b41d102327a92124a22222a760791b60448201526064016102f6565b61193f816060015182608001518360a001518460c001518560e0015186610100015187610120015188610140015161234f565b600c805460ff60a01b191690558051601281905561195e9030906123c1565b6020810151600d80546001600160a01b039283166001600160a01b0319918216179091556040830151600e80549190931691161790556101408101516005906119a79082612c50565b50428161018001516119b99190612b7d565b601355426014556101a08101516018556101608101516016556101c08101516019556101e0810151601a80546001600160a01b03199081166001600160a01b0393841617909155601c8054601d8054909316868516179092558683166001600160b81b031990921691909117600160a01b62ffffff871602179055600d54604080516312a9293f60e21b815290519190921691611aab918391634aa4a4fc9160048083019260209291908290030181865afa158015611a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa09190612b90565b601854836001612480565b50505050505050505050565b60003361188e818585611aca8383611cde565b611ad49190612b7d565b611e3e565b60098054611ae690612bc6565b80601f0160208091040260200160405190810160405280929190818152602001828054611b1290612bc6565b8015611b5f5780601f10611b3457610100808354040283529160200191611b5f565b820191906000526020600020905b815481529060010190602001808311611b4257829003601f168201915b505050505081565b6000601554600003611b7b57506000919050565b6015546001600160a01b038316600090815260106020526040812054601254919291600291611ba991612b2e565b611bb39190612b45565b611bbd9190612b45565b9392505050565b60068054611ae690612bc6565b6060600480546117fd90612bc6565b60003381611bee8286611cde565b905083811015611c4e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016102f6565b6118b38286868403611e3e565b60003361188e818585612135565b60006018546015541115611caf576000601554601854601554611c8c9190612b1b565b6001600160a01b038516600090815260106020526040902054611bb39190612b2e565b506000919050565b600a8054611ae690612bc6565b60088054611ae690612bc6565b60058054611ae690612bc6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60078054611ae690612bc6565b611d536040518060c00160405280600081526020016000815260200160008152602001600081526020016000151581526020016000151581525090565b6040805160c0810182526001600160a01b038416600090815260106020908152929020548152908101611d8584611c69565b8152602001611d9384611b67565b8152600f546020808301919091526001600160a01b039094166000818152601b865260408082205460ff9081161515828601529282526011909652949094205490931615156060909301929092525090565b6002600b5403611e375760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102f6565b6002600b55565b6001600160a01b038316611ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016102f6565b6001600160a01b038216611f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016102f6565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60008060008060006040518061016001604052808b6001600160a01b031681526020018a6001600160a01b03168152602001601c60149054906101000a900462ffffff1662ffffff168152602001620d89b31960020b8152602001620d89b460020b815260200189815260200188815260200160648a6062611fe49190612b2e565b611fee9190612b45565b815260200160646120008a6062612b2e565b61200a9190612b45565b8152601c546020909101906001600160a01b031615612029573061202c565b60005b6001600160a01b0316815260200161204642610e10612b7d565b81525090506000806000808e6001600160a01b031663883164568b876040518363ffffffff1660e01b815260040161207e9190612d10565b60806040518083038185885af115801561209c573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906120c19190612dd4565b93509350935093508e6001600160a01b03166312210e8a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561210457600080fd5b505af1158015612118573d6000803e3d6000fd5b50959a509398509196509450505050509650965096509692505050565b6001600160a01b0383166121995760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016102f6565b6001600160a01b0382166121fb5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016102f6565b6001600160a01b038316600090815260208190526040902054818110156122735760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016102f6565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b60006122e78484611cde565b905060001981146122d557818110156123425760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016102f6565b6122d58484848403611e3e565b600361235b8982612c50565b5060046123688882612c50565b5060066123758782612c50565b5060076123828682612c50565b50600861238f8582612c50565b50600961239c8482612c50565b50600a6123a98382612c50565b5060056123b68282612c50565b505050505050505050565b6001600160a01b0382166124175760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016102f6565b80600260008282546124299190612b7d565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000808080806001600160a01b038916301061249d5788306124a0565b30895b90955093506001600160a01b03891630106124ca578760026012546124c59190612b45565b6124db565b60026012546124d99190612b45565b885b90935091508515612586576124f08383612596565b601c546040516309f56ab160e11b81526001600160a01b0388811660048301528781166024830152600160a01b90920462ffffff16604482015281831660648201529192508816906313ead562906084016020604051808303816000875af1158015612560573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125849190612b90565b505b945094509450945094565b505050565b600080831180156125a75750600082115b6125f35760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e7473206d7573742062652067726561746572207468616e2030000060448201526064016102f6565b60008361260884670de0b6b3a7640000612b2e565b6126129190612b45565b9050600061261f8261263f565b90506000612635633b9aca00606084901b612b45565b9695505050505050565b60008160000361265157506000919050565b81600061265f600283612b45565b61266a906001612b7d565b90505b818110156126a0579050806002816126858187612b45565b61268f9190612b7d565b6126999190612b45565b905061266d565b5092915050565b60006020808352835180602085015260005b818110156126d5578581018301518582016040015282016126b9565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461270b57600080fd5b50565b8035612719816126f6565b919050565b6000806040838503121561273157600080fd5b823561273c816126f6565b946020939093013593505050565b60006020828403121561275c57600080fd5b8135611bbd816126f6565b60008060006060848603121561277c57600080fd5b8335612787816126f6565b92506020840135612797816126f6565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051610200810167ffffffffffffffff811182821017156127e2576127e26127a8565b60405290565b600082601f8301126127f957600080fd5b813567ffffffffffffffff80821115612814576128146127a8565b604051601f8301601f19908116603f0116810190828211818310171561283c5761283c6127a8565b8160405283815286602085880101111561285557600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561288b57600080fd5b8435612896816126f6565b9350602085013562ffffff811681146128ae57600080fd5b925060408501356128be816126f6565b9150606085013567ffffffffffffffff808211156128db57600080fd5b9086019061020082890312156128f057600080fd5b6128f86127be565b823581526129086020840161270e565b60208201526129196040840161270e565b604082015260608301358281111561293057600080fd5b61293c8a8286016127e8565b60608301525060808301358281111561295457600080fd5b6129608a8286016127e8565b60808301525060a08301358281111561297857600080fd5b6129848a8286016127e8565b60a08301525060c08301358281111561299c57600080fd5b6129a88a8286016127e8565b60c08301525060e0830135828111156129c057600080fd5b6129cc8a8286016127e8565b60e08301525061010080840135838111156129e657600080fd5b6129f28b8287016127e8565b8284015250506101208084013583811115612a0c57600080fd5b612a188b8287016127e8565b8284015250506101408084013583811115612a3257600080fd5b612a3e8b8287016127e8565b9183019190915250610160838101359082015261018080840135908201526101a080840135908201526101c080840135908201526101e09150612a8282840161270e565b8282015280935050505092959194509250565b60008060408385031215612aa857600080fd5b8235612ab3816126f6565b91506020830135612ac3816126f6565b809150509250929050565b60208082526019908201527f466169724d696e743a20616c7265616479207374617274656400000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561189457611894612b05565b808202811582820484141761189457611894612b05565b600082612b6257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052600160045260246000fd5b8082018082111561189457611894612b05565b600060208284031215612ba257600080fd5b8151611bbd816126f6565b600060208284031215612bbf57600080fd5b5051919050565b600181811c90821680612bda57607f821691505b602082108103612bfa57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115612591576000816000526020600020601f850160051c81016020861015612c295750805b601f850160051c820191505b81811015612c4857828155600101612c35565b505050505050565b815167ffffffffffffffff811115612c6a57612c6a6127a8565b612c7e81612c788454612bc6565b84612c00565b602080601f831160018114612cb35760008415612c9b5750858301515b600019600386901b1c1916600185901b178555612c48565b600085815260208120601f198616915b82811015612ce257888601518255948401946001909101908401612cc3565b5085821015612d005787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81516001600160a01b0316815261016081016020830151612d3c60208401826001600160a01b03169052565b506040830151612d53604084018262ffffff169052565b506060830151612d68606084018260020b9052565b506080830151612d7d608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151612dc3828501826001600160a01b03169052565b505061014092830151919092015290565b60008060008060808587031215612dea57600080fd5b8451935060208501516001600160801b0381168114612e0857600080fd5b604086015160609096015194979096509250505056fea2646970667358221220008622ac145d9e8c37b8e4f1a6ea0adc48a273d0b20bb14ed3af1a0458af834964736f6c63430008180033a2646970667358221220d46449eb5f31c2b929dfc3fd9b8c437242c889f678faf4e97ea4c838f3249c6a64736f6c63430008180033000000000000000000000000ae52bd54742bd12b4ecf15cc35161d75d8af7481000000000000000000000000b7f74a16565e8cff8b4ad8a60b68c9af9055d81c000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe880000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984
Deployed Bytecode
0x60806040526004361061021a5760003560e01c8063a0c05c0611610123578063c283c5c3116100ab578063f002606b1161006f578063f002606b14610663578063f2fde38b14610679578063f46901ed14610699578063f570ee6b146106b9578063f885a2a3146106cf57600080fd5b8063c283c5c3146105af578063c8a56831146105cf578063c92a4b9d146105ef578063d160c7a91461060f578063d7b96d4e1461062f57600080fd5b8063aee13348116100f2578063aee133481461050f578063b0a4d7d31461052f578063b512b8151461054f578063b66fd04c1461056f578063bdc30c5a1461058f57600080fd5b8063a0c05c061461048c578063a7cd52cb146104ac578063a807c5db146104dc578063a8a65a78146104ef57600080fd5b8063715018a6116101a65780638da5cb5b116101755780638da5cb5b146103ea57806391b7f5ed14610408578063975fc5d8146104285780639d49ae9d14610448578063a035b1fe1461047657600080fd5b8063715018a614610389578063716042451461039e57806379db6346146103b45780638aee8127146103ca57600080fd5b806332c4f2bf116101ed57806332c4f2bf146102c457806348d041ae146102da5780634b46c65c146102fc578063544d46a31461033c5780636e0918251461035c57600080fd5b8063017e7e581461021f5780630f9147a91461025c5780631736a091146102805780632ab4d052146102ae575b600080fd5b34801561022b57600080fd5b5060035461023f906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561026857600080fd5b5061027260085481565b604051908152602001610253565b34801561028c57600080fd5b506102a061029b366004611ff4565b6106ef565b60405161025392919061203a565b3480156102ba57600080fd5b5061027260075481565b3480156102d057600080fd5b50610272600b5481565b3480156102e657600080fd5b506102fa6102f53660046120b0565b6108c3565b005b34801561030857600080fd5b5061032c6103173660046120b0565b60136020526000908152604090205460ff1681565b6040519015158152602001610253565b34801561034857600080fd5b50600a5461023f906001600160a01b031681565b34801561036857600080fd5b5061037c6103773660046120b0565b6109f6565b6040516102539190612135565b34801561039557600080fd5b506102fa610d65565b3480156103aa57600080fd5b5061027260055481565b3480156103c057600080fd5b5061027260065481565b3480156103d657600080fd5b506102fa6103e53660046120b0565b610d79565b3480156103f657600080fd5b506000546001600160a01b031661023f565b34801561041457600080fd5b506102fa610423366004612144565b610da3565b34801561043457600080fd5b506102fa610443366004612144565b610db0565b34801561045457600080fd5b50610468610463366004611ff4565b610dbd565b60405161025392919061215d565b34801561048257600080fd5b5061027260025481565b34801561049857600080fd5b506104686104a73660046121b5565b610f25565b3480156104b857600080fd5b5061032c6104c73660046120b0565b600c6020526000908152604090205460ff1681565b61023f6104ea3660046122b7565b611032565b3480156104fb57600080fd5b506102fa61050a366004612144565b611482565b34801561051b57600080fd5b506102fa61052a3660046124c4565b61148f565b34801561053b57600080fd5b506102fa61054a3660046124f0565b6115f9565b34801561055b57600080fd5b506102fa61056a366004612144565b61160c565b34801561057b57600080fd5b506102fa61058a366004612144565b611619565b34801561059b57600080fd5b506104686105aa366004611ff4565b611626565b3480156105bb57600080fd5b506102fa6105ca3660046120b0565b611762565b3480156105db57600080fd5b506102fa6105ea366004612512565b61178c565b3480156105fb57600080fd5b5061046861060a3660046121b5565b61181f565b34801561061b57600080fd5b506102fa61062a3660046124f0565b61192c565b34801561063b57600080fd5b5061023f7f000000000000000000000000b7f74a16565e8cff8b4ad8a60b68c9af9055d81c81565b34801561066f57600080fd5b5061027260045481565b34801561068557600080fd5b506102fa6106943660046120b0565b61193f565b3480156106a557600080fd5b506102fa6106b43660046120b0565b6119b5565b3480156106c557600080fd5b5061027260095481565b3480156106db57600080fd5b506102fa6106ea3660046124c4565b6119df565b6001600160a01b038316600090815260126020526040812060609190819061071690611b56565b905080841061072d5761072a600182612569565b93505b60006107398686612569565b61074490600161257c565b905060008167ffffffffffffffff811115610761576107616121ea565b6040519080825280602002602001820160405280156107c657816020015b6107b3604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b81526020019060019003908161077f5790505b5090506000875b8781116108b25760116108188c6107e457826107fa565b826107f0600189612569565b6107fa9190612569565b6001600160a01b038d16600090815260126020526040902090611b66565b815481106108285761082861258f565b600091825260209182902060408051608081018252600490930290910180546001600160a01b03168352600181015493830193909352600283015490820152600390910154606082015283518490849081106108865761088661258f565b6020026020010181905250818061089c906125a5565b92505080806108aa906125a5565b9150506107cd565b509099929850919650505050505050565b3360009081526013602052604090205460ff166108fb5760405162461bcd60e51b81526004016108f2906125be565b60405180910390fd5b600e80546001810182556000919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b031916331790556015546001600160a01b0316156109f3576015546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb91906125ea565b905060006014541180156109d157506014548110155b156109f1576015546014546109f1916001600160a01b0316908490611b72565b505b50565b6109fe611f54565b6000829050604051806101200160405280826001600160a01b031663a4475ce46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a719190612603565b6001600160a01b03168152602001826001600160a01b03168152602001826001600160a01b031663f570ee6b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af091906125ea565b8152602001826001600160a01b0316630a4625af6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5791906125ea565b8152602001826001600160a01b0316639e35b6916040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbe91906125ea565b8152602001826001600160a01b031663d4067abf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2591906125ea565b8152602001826001600160a01b031663c2e386c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c91906125ea565b8152602001826001600160a01b0316630f9147a96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf391906125ea565b8152602001826001600160a01b0316631f2698ab6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5a9190612620565b151590529392505050565b610d6d611c8d565b610d776000611ce7565b565b610d81611c8d565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b610dab611c8d565b600255565b610db8611c8d565b600855565b6001600160a01b0383166000908152601060205260408120606091908190610de490611b56565b9050808410610dfb57610df8600182612569565b93505b6000610e078686612569565b610e1290600161257c565b905060008167ffffffffffffffff811115610e2f57610e2f6121ea565b604051908082528060200260200182016040528015610e6857816020015b610e55611f54565b815260200190600190039081610e4d5790505b5090506000875b8781116108b257610ee7600d610ebd8d610e895783610e9f565b83610e9560018a612569565b610e9f9190612569565b6001600160a01b038e16600090815260106020526040902090611b66565b81548110610ecd57610ecd61258f565b6000918252602090912001546001600160a01b03166109f6565b838381518110610ef957610ef961258f565b60200260200101819052508180610f0f906125a5565b9250508080610f1d906125a5565b915050610e6f565b600e54606090600090808410610f4357610f40600182612569565b93505b6000610f4f8686612569565b610f5a90600161257c565b905060008167ffffffffffffffff811115610f7757610f776121ea565b604051908082528060200260200182016040528015610fb057816020015b610f9d611f54565b815260200190600190039081610f955790505b5090506000875b87811161102257610fe4600e8b610fce5782610ebd565b82610fda600189612569565b610ebd9190612569565b838381518110610ff657610ff661258f565b6020026020010181905250818061100c906125a5565b925050808061101a906125a5565b915050610fb7565b5090989297509195505050505050565b600061103c611d37565b600b546101c0830152600a546001600160a01b03166101e08301526009546101a083015260085461016083015260065482511080159061107f5750600754825111155b6110cb5760405162461bcd60e51b815260206004820152601a60248201527f696e76616c6964206c61756e636820746f74616c537570706c7900000000000060448201526064016108f2565b600454826101800151101580156110e9575060055482610180015111155b6111355760405162461bcd60e51b815260206004820152601860248201527f696e76616c6964206c61756e63682074696d657374616d70000000000000000060448201526064016108f2565b6040808301516001600160a01b03166000908152600c602052205460ff16801561117c57506020808301516001600160a01b03166000908152600c909152604090205460ff165b6111e25760405162461bcd60e51b815260206004820152603160248201527f556e697377617020666163746f7279206f7220726f757465722073686f756c646044820152701031329034b71030b63637bbb634b9ba1760791b60648201526084016108f2565b6003546001600160a01b0316158015906111fe57506000600254115b156112e25760025434101561124a5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e7420707269636560701b60448201526064016108f2565b6003546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611297576040519150601f19603f3d011682016040523d82523d6000602084013e61129c565b606091505b50509050806112e05760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016108f2565b505b60006040516112f090611fb4565b604051809103906000f08015801561130c573d6000803e3d6000fd5b50604051629e47b760e61b81529091506001600160a01b03821690632791edc090611361907f000000000000000000000000b7f74a16565e8cff8b4ad8a60b68c9af9055d81c9088908a90899060040161268d565b600060405180830381600087803b15801561137b57600080fd5b505af115801561138f573d6000803e3d6000fd5b5050600d80546001808201835560008390527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb590910180546001600160a01b0319166001600160a01b0387161790559054939450849361141293506113f49250612569565b6001600160a01b038716600090815260106020526040902090611d90565b506001600160a01b03821660008181526013602052604090819020805460ff19166001179055517fb03c53b28e78a88e31607a27e1fa48234dce28d5d9d9ec7b295aeb02e674a1e190611469906002815260200190565b60405180910390a25061147b60018055565b9392505050565b61148a611c8d565b601455565b3360009081526013602052604090205460ff166114be5760405162461bcd60e51b81526004016108f2906125be565b6001600160a01b0382166000908152600f602052604090206114e09033611d9c565b50604080516080810182526001600160a01b03848116825260026020830190815292820184815242606084019081526011805460018082018355600083905295517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600490920291820180546001600160a01b031916919096161790945594517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6984015590517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b9091015590546115f4916115df91612569565b33600090815260126020526040902090611d90565b505050565b611601611c8d565b600691909155600755565b611614611c8d565b600b55565b611621611c8d565b600955565b6001600160a01b0383166000908152600f6020526040812060609190819061164d90611b56565b905080841061166457611661600182612569565b93505b60006116708686612569565b61167b90600161257c565b905060008167ffffffffffffffff811115611698576116986121ea565b6040519080825280602002602001820160405280156116d157816020015b6116be611f54565b8152602001906001900390816116b65790505b5090506000875b8781116108b2576117246103778c6116f05782611706565b826116fc600189612569565b6117069190612569565b6001600160a01b038d166000908152600f6020526040902090611b66565b8383815181106117365761173661258f565b6020026020010181905250818061174c906125a5565b925050808061175a906125a5565b9150506116d8565b61176a611c8d565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b611794611c8d565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa1580156117db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ff91906125ea565b905061181984848484116118135783611b72565b84611b72565b50505050565b600d54606090600090831061184057600d5461183d90600190612569565b92505b600061184c8585612569565b61185790600161257c565b905060008167ffffffffffffffff811115611874576118746121ea565b6040519080825280602002602001820160405280156118ad57816020015b61189a611f54565b8152602001906001900390816118925790505b5090506000865b86811161191a576118dc600d8a6118cb5782610ebd565b600d548390610fda90600190612569565b8383815181106118ee576118ee61258f565b60200260200101819052508180611904906125a5565b9250508080611912906125a5565b9150506118b4565b5050600d549097909650945050505050565b611934611c8d565b600491909155600555565b611947611c8d565b6001600160a01b0381166119ac5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108f2565b6109f381611ce7565b6119bd611c8d565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b3360009081526013602052604090205460ff16611a0e5760405162461bcd60e51b81526004016108f2906125be565b6001600160a01b0382166000908152600f60205260409020611a309033611db1565b611a58576001600160a01b0382166000908152600f60205260409020611a569033611dd3565b505b604080516080810182526001600160a01b0384811682526001602083018181529383018581524260608501908152601180548085018255600082905295517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600490970296870180546001600160a01b031916919096161790945594517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69850155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a84015592517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b90920191909155546115f4916115df91612569565b6000611b60825490565b92915050565b600061147b8383611de8565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611bce919061283a565b6000604051808303816000865af19150503d8060008114611c0b576040519150601f19603f3d011682016040523d82523d6000602084013e611c10565b606091505b5091509150818015611c3a575080511580611c3a575080806020019051810190611c3a9190612620565b611c865760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016108f2565b5050505050565b6000546001600160a01b03163314610d775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108f2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600260015403611d895760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016108f2565b6002600155565b600061147b8383611e12565b600061147b836001600160a01b038416611e61565b6001600160a01b0381166000908152600183016020526040812054151561147b565b600061147b836001600160a01b038416611e12565b6000826000018281548110611dff57611dff61258f565b9060005260206000200154905092915050565b6000818152600183016020526040812054611e5957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611b60565b506000611b60565b60008181526001830160205260408120548015611f4a576000611e85600183612569565b8554909150600090611e9990600190612569565b9050818114611efe576000866000018281548110611eb957611eb961258f565b9060005260206000200154905080876000018481548110611edc57611edc61258f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f0f57611f0f612856565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b60565b6000915050611b60565b60405180610120016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b612e9b8061286d83390190565b80151581146109f357600080fd5b6001600160a01b03811681146109f357600080fd5b8035611fef81611fcf565b919050565b6000806000806080858703121561200a57600080fd5b843561201581611fc1565b9350602085013561202581611fcf565b93969395505050506040820135916060013590565b6040808252835182820181905260009190606090818501906020808901865b8381101561209957815180516001600160a01b03168652838101518487015287810151888701528601518686015260809094019390820190600101612059565b505050508093505050508260208301529392505050565b6000602082840312156120c257600080fd5b813561147b81611fcf565b60018060a01b038082511683528060208301511660208401525060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e083015261010080820151151581840152505050565b6101208101611b6082846120cd565b60006020828403121561215657600080fd5b5035919050565b604080825283519082018190526000906020906060840190828701845b828110156121a15761218d8483516120cd565b61012093909301929084019060010161217a565b505050602093909301939093525092915050565b6000806000606084860312156121ca57600080fd5b83356121d581611fc1565b95602085013595506040909401359392505050565b634e487b7160e01b600052604160045260246000fd5b604051610200810167ffffffffffffffff81118282101715612224576122246121ea565b60405290565b600082601f83011261223b57600080fd5b813567ffffffffffffffff80821115612256576122566121ea565b604051601f8301601f19908116603f0116810190828211818310171561227e5761227e6121ea565b8160405283815286602085880101111561229757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156122cc57600080fd5b83356122d781611fcf565b9250602084013562ffffff811681146122ef57600080fd5b9150604084013567ffffffffffffffff8082111561230c57600080fd5b90850190610200828803121561232157600080fd5b612329612200565b8235815261233960208401611fe4565b602082015261234a60408401611fe4565b604082015260608301358281111561236157600080fd5b61236d8982860161222a565b60608301525060808301358281111561238557600080fd5b6123918982860161222a565b60808301525060a0830135828111156123a957600080fd5b6123b58982860161222a565b60a08301525060c0830135828111156123cd57600080fd5b6123d98982860161222a565b60c08301525060e0830135828111156123f157600080fd5b6123fd8982860161222a565b60e083015250610100808401358381111561241757600080fd5b6124238a82870161222a565b828401525050610120808401358381111561243d57600080fd5b6124498a82870161222a565b828401525050610140808401358381111561246357600080fd5b61246f8a82870161222a565b9183019190915250610160838101359082015261018080840135908201526101a080840135908201526101c080840135908201526101e091506124b3828401611fe4565b828201528093505050509250925092565b600080604083850312156124d757600080fd5b82356124e281611fcf565b946020939093013593505050565b6000806040838503121561250357600080fd5b50508035926020909101359150565b60008060006060848603121561252757600080fd5b833561253281611fcf565b9250602084013561254281611fcf565b929592945050506040919091013590565b634e487b7160e01b600052601160045260246000fd5b81810381811115611b6057611b60612553565b80820180821115611b6057611b60612553565b634e487b7160e01b600052603260045260246000fd5b6000600182016125b7576125b7612553565b5060010190565b60208082526012908201527127379034b9902630bab731b4102a37b5b2b760711b604082015260600190565b6000602082840312156125fc57600080fd5b5051919050565b60006020828403121561261557600080fd5b815161147b81611fcf565b60006020828403121561263257600080fd5b815161147b81611fc1565b60005b83811015612658578181015183820152602001612640565b50506000910152565b6000815180845261267981602086016020860161263d565b601f01601f19169290920160200192915050565b600060018060a01b03808716835262ffffff86166020840152808516604084015250608060608301528251608083015260208301516126d760a08401826001600160a01b03169052565b5060408301516001600160a01b031660c0830152606083015161020060e08401819052612708610280850183612661565b91506080850151607f196101008187860301818801526127288584612661565b945060a088015192506101208288870301818901526127478685612661565b955060c089015193506101408389880301818a01526127668786612661565b965060e08a01519450610160848a890301818b01526127858887612661565b9750838b015195506101809350848a890301848b01526127a58887612661565b9750828b015195506101a09250848a890301838b01526127c58887612661565b9750818b015195506101c09150848a890301828b01526127e58887612661565b908b01516101e08b810191909152938b0151968a0196909652908901516102208901528801516102408801528701516001600160a01b03811661026088015292935061282f915050565b509695505050505050565b6000825161284c81846020870161263d565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe60a060405234801561001057600080fd5b506001600b5530608052600c80546001600160a01b03191633179055608051612e546100476000396000610a2b0152612e546000f3fe6080604052600436106102765760003560e01c8063996eba2d1161014f578063c884ef83116100c1578063e1fad57b1161007a578063e1fad57b14610937578063e5047b301461094d578063ec3090381461096d578063f3ccaac014610985578063f570ee6b1461099a578063ffc9896b146109b057600080fd5b8063c884ef831461086f578063c885044e1461089f578063d35e7efc146108b4578063d4067abf146108e1578063d7b96d4e146108f7578063dd62ed3e1461091757600080fd5b8063a9059cbb11610113578063a9059cbb146107cf578063a92bc58a146107ef578063abfaeee01461080f578063b17249a114610824578063beb0a41614610844578063c2e386c01461085957600080fd5b8063996eba2d146107465780639e35b691146107605780639ecf009014610776578063a4475ce41461078f578063a457c2d7146107af57600080fd5b806332c4f2bf116101e857806368b63c24116101ac57806368b63c241461069057806370a08231146106b05780637284e416146106e65780637b0fa954146106fb5780638bdb2afa1461071157806395d89b411461073157600080fd5b806332c4f2bf146105f35780633950935114610609578063475a519f1461062957806347ecb66514610643578063544d46a31461065857600080fd5b806318160ddd1161023a57806318160ddd146105315780631e7269c5146105465780631f2698ab1461057657806323b872dd146105975780632791edc0146105b7578063313ce567146105d757600080fd5b806306fdde0314610465578063089fe6aa14610490578063095ea7b3146104c75780630a4625af146104f75780630f9147a91461051b57600080fd5b3661046057610283610a20565b600d546001600160a01b0316331461031d573233146102ff5760405162461bcd60e51b815260206004820152602d60248201527f466169724d696e743a2063616e206e6f742073656e6420636f6d6d616e64206660448201526c3937b69031b7b73a3930b1ba1760991b60648201526084015b60405180910390fd5b60135442106104435765b5e620f48000340361031f5761031d610a57565b005b655af3107a40003403610409576018546015541015801561034a5750600c54600160a01b900460ff16155b1561035757610357610d88565b61035f611169565b601854601554111561037357610373611327565b6040516000903390655af3107a4000908381818185875af1925050503d80600081146103bb576040519150601f19603f3d011682016040523d82523d6000602084013e6103c0565b606091505b505090508061031d5760405162461bcd60e51b815260206004820152601560248201527411985a5c935a5b9d0e881b5a5b9d0819985a5b1959605a1b60448201526064016102f6565b60405162461bcd60e51b815260206004820152600f60248201526e466169724d696e743a20636c61696d60881b60448201526064016102f6565b65b5e620f4800034036104585761031d610a57565b61031d6115e7565b600080fd5b34801561047157600080fd5b5061047a6117ee565b60405161048791906126a7565b60405180910390f35b34801561049c57600080fd5b50601c546104b390600160a01b900462ffffff1681565b60405162ffffff9091168152602001610487565b3480156104d357600080fd5b506104e76104e236600461271e565b611880565b6040519015158152602001610487565b34801561050357600080fd5b5061050d60155481565b604051908152602001610487565b34801561052757600080fd5b5061050d60165481565b34801561053d57600080fd5b5060025461050d565b34801561055257600080fd5b506104e761056136600461274a565b60116020526000908152604090205460ff1681565b34801561058257600080fd5b50600c546104e790600160a01b900460ff1681565b3480156105a357600080fd5b506104e76105b2366004612767565b61189a565b3480156105c357600080fd5b5061031d6105d2366004612875565b6118be565b3480156105e357600080fd5b5060405160128152602001610487565b3480156105ff57600080fd5b5061050d60195481565b34801561061557600080fd5b506104e761062436600461271e565b611ab7565b34801561063557600080fd5b5061050d655af3107a400081565b34801561064f57600080fd5b5061047a611ad9565b34801561066457600080fd5b50601a54610678906001600160a01b031681565b6040516001600160a01b039091168152602001610487565b34801561069c57600080fd5b5061050d6106ab36600461274a565b611b67565b3480156106bc57600080fd5b5061050d6106cb36600461274a565b6001600160a01b031660009081526020819052604090205490565b3480156106f257600080fd5b5061047a611bc4565b34801561070757600080fd5b5061050d60125481565b34801561071d57600080fd5b50600e54610678906001600160a01b031681565b34801561073d57600080fd5b5061047a611bd1565b34801561075257600080fd5b5061050d65b5e620f4800081565b34801561076c57600080fd5b5061050d60135481565b34801561078257600080fd5b5061050d64e8d4a5100081565b34801561079b57600080fd5b50601d54610678906001600160a01b031681565b3480156107bb57600080fd5b506104e76107ca36600461271e565b611be0565b3480156107db57600080fd5b506104e76107ea36600461271e565b611c5b565b3480156107fb57600080fd5b5061050d61080a36600461274a565b611c69565b34801561081b57600080fd5b5061047a611cb7565b34801561083057600080fd5b50600c54610678906001600160a01b031681565b34801561085057600080fd5b5061047a611cc4565b34801561086557600080fd5b5061050d60175481565b34801561087b57600080fd5b506104e761088a36600461274a565b601b6020526000908152604090205460ff1681565b3480156108ab57600080fd5b5061047a611cd1565b3480156108c057600080fd5b5061050d6108cf36600461274a565b60106020526000908152604090205481565b3480156108ed57600080fd5b5061050d60145481565b34801561090357600080fd5b50601c54610678906001600160a01b031681565b34801561092357600080fd5b5061050d610932366004612a95565b611cde565b34801561094357600080fd5b5061050d600f5481565b34801561095957600080fd5b50600d54610678906001600160a01b031681565b34801561097957600080fd5b506013544210156104e7565b34801561099157600080fd5b5061047a611d09565b3480156109a657600080fd5b5061050d60185481565b3480156109bc57600080fd5b506109d06109cb36600461274a565b611d16565b6040516104879190600060c0820190508251825260208301516020830152604083015160408301526060830151606083015260808301511515608083015260a0830151151560a083015292915050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a5557600080fd5b565b610a5f611de5565b600c54600160a01b900460ff1615610a895760405162461bcd60e51b81526004016102f690612ace565b3360008181526010602052604090205480610ada5760405162461bcd60e51b815260206004820152601160248201527011985a5c935a5b9d0e881b9bc8199d5b99607a1b60448201526064016102f6565b6001600160a01b038216600090815260106020526040812081905560158054839290610b07908490612b1b565b92505081905550600160176000828254610b219190612b1b565b9091555050600c546040516315dc266960e31b8152336004820152602481018390526001600160a01b039091169063aee1334890604401600060405180830381600087803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b50505050600061271060195483610b9d9190612b2e565b610ba79190612b45565b9050818110610bb857610bb8612b67565b600081118015610bd25750601a546001600160a01b031615155b15610c7c57601a546040516000916001600160a01b03169083908381818185875af1925050503d8060008114610c24576040519150601f19603f3d011682016040523d82523d6000602084013e610c29565b606091505b5050905080610c7a5760405162461bcd60e51b815260206004820152601b60248201527f466169724d696e743a20726566756e6420666565206661696c6564000000000060448201526064016102f6565b505b60006001600160a01b03841665b5e620f48000610c998486612b1b565b610ca39190612b7d565b604051600081818185875af1925050503d8060008114610cdf576040519150601f19603f3d011682016040523d82523d6000602084013e610ce4565b606091505b5050905080610d355760405162461bcd60e51b815260206004820152601760248201527f466169724d696e743a20726566756e64206661696c656400000000000000000060448201526064016102f6565b6040805160008152602081018590526001600160a01b038616917fb24b09fd2e8e4d8904c3c26f3e935824e032891520ffda419dec9f086b0e1eea910160405180910390a250505050610a556001600b55565b610d90611de5565b600c54600160a01b900460ff1615610dba5760405162461bcd60e51b81526004016102f690612ace565b3060009081526020819052604081205411610e0e5760405162461bcd60e51b8152602060048201526014602482015273466169724d696e743a206e6f2062616c616e636560601b60448201526064016102f6565b600d54604080516312a9293f60e21b815290516001600160a01b03909216916000918391634aa4a4fc916004808201926020929091908290030181865afa158015610e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e819190612b90565b601854600d5491925090610ea29030906001600160a01b0316600019611e3e565b6000806001600160a01b0384163010610ebc578330610ebf565b30845b90925090506000806001600160a01b0386163010610eec57846002601254610ee79190612b45565b610efd565b6002601254610efb9190612b45565b855b91509150600080600080610f158b898989898e611f62565b600c8054600160a01b60ff60a01b19821617909155601d5460405163246820d760e11b81526001600160a01b039182166004820152959950939750919550935016906348d041ae90602401600060405180830381600087803b158015610f7a57600080fd5b505af1158015610f8e573d6000803e3d6000fd5b505060408051858152602081018590526001600160801b0387168183015290513093507fef1e73540aed31615f5f09b178cff91261e831560c37718c23862e93a3fc3ceb92509081900360600190a2601c546001600160a01b03161561115457600d54601c5460405163095ea7b360e01b81526001600160a01b0391821660048201526024810187905291169063095ea7b390604401600060405180830381600087803b15801561103e57600080fd5b505af1158015611052573d6000803e3d6000fd5b5050601c54600d5460405163e2ab691d60e01b81526001600160a01b0391821660048201526024810189905260001960448201529116925060009150829063e2ab691d906064016020604051808303816000875af11580156110b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dc9190612bad565b600f819055601c54601d546040516323b872dd60e01b81523060048201526001600160a01b0391821660248201526044810184905292935016906323b872dd90606401600060405180830381600087803b15801561113957600080fd5b505af115801561114d573d6000803e3d6000fd5b5050505050505b5050505050505050505050610a556001600b55565b611171611de5565b600c54600160a01b900460ff166111c25760405162461bcd60e51b815260206004820152601560248201527411985a5c935a5b9d0e881b9bdd081cdd185c9d1959605a1b60448201526064016102f6565b33321461121d5760405162461bcd60e51b815260206004820152602360248201527f466169724d696e743a2063616e206e6f74206d696e7420746f20636f6e74726160448201526231ba1760e91b60648201526084016102f6565b3360009081526011602052604090205460ff161561127d5760405162461bcd60e51b815260206004820152601860248201527f466169724d696e743a20616c7265616479206d696e746564000000000000000060448201526064016102f6565b336000818152601160205260408120805460ff19166001179055906112a190611b67565b9050600081116112f35760405162461bcd60e51b815260206004820152601d60248201527f466169724d696e743a206d696e7420616d6f756e74206973207a65726f00000060448201526064016102f6565b60026012546113029190612b45565b81111561131157611311612b67565b61131c303383612135565b50610a556001600b55565b61132f611de5565b600c54600160a01b900460ff1661139e5760405162461bcd60e51b815260206004820152602d60248201527f466169724d696e743a20776974686472617720657874726120657468206d757360448201526c1d0818599d195c881cdd185c9d609a1b60648201526084016102f6565b6000601854116113fb5760405162461bcd60e51b815260206004820152602260248201527f466169724d696e743a20736f667420746f7020636170206d7573742062652073604482015261195d60f21b60648201526084016102f6565b601854601554116114475760405162461bcd60e51b815260206004820152601660248201527508cc2d2e49ad2dce87440dcde40caf0e8e4c240cae8d60531b60448201526064016102f6565b60006018546015546114599190612b1b565b33600090815260106020526040902054909150806114ad5760405162461bcd60e51b815260206004820152601160248201527011985a5c935a5b9d0e881b9bc8199d5b99607a1b60448201526064016102f6565b336000908152601b602052604090205460ff161561150d5760405162461bcd60e51b815260206004820152601960248201527f466169724d696e743a20616c726561647920636c61696d65640000000000000060448201526064016102f6565b336000908152601b60205260408120805460ff191660011790556015546115348484612b2e565b61153e9190612b45565b604051909150600090339083908381818185875af1925050503d8060008114611583576040519150601f19603f3d011682016040523d82523d6000602084013e611588565b606091505b50509050806115d95760405162461bcd60e51b815260206004820152601960248201527f466169724d696e743a207769746864726177206661696c65640000000000000060448201526064016102f6565b50505050610a556001600b55565b6115ef611de5565b600c54600160a01b900460ff16156116195760405162461bcd60e51b81526004016102f690612ace565b64e8d4a5100034101561166e5760405162461bcd60e51b815260206004820152601760248201527f466169724d696e743a2076616c756520746f6f206c6f7700000000000000000060448201526064016102f6565b6016543360009081526010602052604090205461168b9034612b7d565b11156116d95760405162461bcd60e51b815260206004820152601860248201527f466169724d696e743a2076616c756520746f6f2068696768000000000000000060448201526064016102f6565b336000908152601060205260408120549003611708576001601760008282546117029190612b7d565b90915550505b600c5460405163f885a2a360e01b81523360048201523460248201526001600160a01b039091169063f885a2a390604401600060405180830381600087803b15801561175357600080fd5b505af1158015611767573d6000803e3d6000fd5b5050336000908152601060205260408120805434945090925061178b908490612b7d565b9250508190555034601560008282546117a49190612b7d565b9091555050604080513481526000602082015233917f4c10b3a5590fcdc7a6f3b564c09870bd275facbd00a0bcf68c8b069e32f9508b910160405180910390a2610a556001600b55565b6060600380546117fd90612bc6565b80601f016020809104026020016040519081016040528092919081815260200182805461182990612bc6565b80156118765780601f1061184b57610100808354040283529160200191611876565b820191906000526020600020905b81548152906001019060200180831161185957829003601f168201915b5050505050905090565b60003361188e818585611e3e565b60019150505b92915050565b6000336118a88582856122db565b6118b3858585612135565b506001949350505050565b600c546001600160a01b0316331461190c5760405162461bcd60e51b81526020600482015260116024820152702630bab731b41d102327a92124a22222a760791b60448201526064016102f6565b61193f816060015182608001518360a001518460c001518560e0015186610100015187610120015188610140015161234f565b600c805460ff60a01b191690558051601281905561195e9030906123c1565b6020810151600d80546001600160a01b039283166001600160a01b0319918216179091556040830151600e80549190931691161790556101408101516005906119a79082612c50565b50428161018001516119b99190612b7d565b601355426014556101a08101516018556101608101516016556101c08101516019556101e0810151601a80546001600160a01b03199081166001600160a01b0393841617909155601c8054601d8054909316868516179092558683166001600160b81b031990921691909117600160a01b62ffffff871602179055600d54604080516312a9293f60e21b815290519190921691611aab918391634aa4a4fc9160048083019260209291908290030181865afa158015611a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa09190612b90565b601854836001612480565b50505050505050505050565b60003361188e818585611aca8383611cde565b611ad49190612b7d565b611e3e565b60098054611ae690612bc6565b80601f0160208091040260200160405190810160405280929190818152602001828054611b1290612bc6565b8015611b5f5780601f10611b3457610100808354040283529160200191611b5f565b820191906000526020600020905b815481529060010190602001808311611b4257829003601f168201915b505050505081565b6000601554600003611b7b57506000919050565b6015546001600160a01b038316600090815260106020526040812054601254919291600291611ba991612b2e565b611bb39190612b45565b611bbd9190612b45565b9392505050565b60068054611ae690612bc6565b6060600480546117fd90612bc6565b60003381611bee8286611cde565b905083811015611c4e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016102f6565b6118b38286868403611e3e565b60003361188e818585612135565b60006018546015541115611caf576000601554601854601554611c8c9190612b1b565b6001600160a01b038516600090815260106020526040902054611bb39190612b2e565b506000919050565b600a8054611ae690612bc6565b60088054611ae690612bc6565b60058054611ae690612bc6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60078054611ae690612bc6565b611d536040518060c00160405280600081526020016000815260200160008152602001600081526020016000151581526020016000151581525090565b6040805160c0810182526001600160a01b038416600090815260106020908152929020548152908101611d8584611c69565b8152602001611d9384611b67565b8152600f546020808301919091526001600160a01b039094166000818152601b865260408082205460ff9081161515828601529282526011909652949094205490931615156060909301929092525090565b6002600b5403611e375760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102f6565b6002600b55565b6001600160a01b038316611ea05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016102f6565b6001600160a01b038216611f015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016102f6565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60008060008060006040518061016001604052808b6001600160a01b031681526020018a6001600160a01b03168152602001601c60149054906101000a900462ffffff1662ffffff168152602001620d89b31960020b8152602001620d89b460020b815260200189815260200188815260200160648a6062611fe49190612b2e565b611fee9190612b45565b815260200160646120008a6062612b2e565b61200a9190612b45565b8152601c546020909101906001600160a01b031615612029573061202c565b60005b6001600160a01b0316815260200161204642610e10612b7d565b81525090506000806000808e6001600160a01b031663883164568b876040518363ffffffff1660e01b815260040161207e9190612d10565b60806040518083038185885af115801561209c573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906120c19190612dd4565b93509350935093508e6001600160a01b03166312210e8a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561210457600080fd5b505af1158015612118573d6000803e3d6000fd5b50959a509398509196509450505050509650965096509692505050565b6001600160a01b0383166121995760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016102f6565b6001600160a01b0382166121fb5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016102f6565b6001600160a01b038316600090815260208190526040902054818110156122735760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016102f6565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b60006122e78484611cde565b905060001981146122d557818110156123425760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016102f6565b6122d58484848403611e3e565b600361235b8982612c50565b5060046123688882612c50565b5060066123758782612c50565b5060076123828682612c50565b50600861238f8582612c50565b50600961239c8482612c50565b50600a6123a98382612c50565b5060056123b68282612c50565b505050505050505050565b6001600160a01b0382166124175760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016102f6565b80600260008282546124299190612b7d565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000808080806001600160a01b038916301061249d5788306124a0565b30895b90955093506001600160a01b03891630106124ca578760026012546124c59190612b45565b6124db565b60026012546124d99190612b45565b885b90935091508515612586576124f08383612596565b601c546040516309f56ab160e11b81526001600160a01b0388811660048301528781166024830152600160a01b90920462ffffff16604482015281831660648201529192508816906313ead562906084016020604051808303816000875af1158015612560573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125849190612b90565b505b945094509450945094565b505050565b600080831180156125a75750600082115b6125f35760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e7473206d7573742062652067726561746572207468616e2030000060448201526064016102f6565b60008361260884670de0b6b3a7640000612b2e565b6126129190612b45565b9050600061261f8261263f565b90506000612635633b9aca00606084901b612b45565b9695505050505050565b60008160000361265157506000919050565b81600061265f600283612b45565b61266a906001612b7d565b90505b818110156126a0579050806002816126858187612b45565b61268f9190612b7d565b6126999190612b45565b905061266d565b5092915050565b60006020808352835180602085015260005b818110156126d5578581018301518582016040015282016126b9565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461270b57600080fd5b50565b8035612719816126f6565b919050565b6000806040838503121561273157600080fd5b823561273c816126f6565b946020939093013593505050565b60006020828403121561275c57600080fd5b8135611bbd816126f6565b60008060006060848603121561277c57600080fd5b8335612787816126f6565b92506020840135612797816126f6565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051610200810167ffffffffffffffff811182821017156127e2576127e26127a8565b60405290565b600082601f8301126127f957600080fd5b813567ffffffffffffffff80821115612814576128146127a8565b604051601f8301601f19908116603f0116810190828211818310171561283c5761283c6127a8565b8160405283815286602085880101111561285557600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561288b57600080fd5b8435612896816126f6565b9350602085013562ffffff811681146128ae57600080fd5b925060408501356128be816126f6565b9150606085013567ffffffffffffffff808211156128db57600080fd5b9086019061020082890312156128f057600080fd5b6128f86127be565b823581526129086020840161270e565b60208201526129196040840161270e565b604082015260608301358281111561293057600080fd5b61293c8a8286016127e8565b60608301525060808301358281111561295457600080fd5b6129608a8286016127e8565b60808301525060a08301358281111561297857600080fd5b6129848a8286016127e8565b60a08301525060c08301358281111561299c57600080fd5b6129a88a8286016127e8565b60c08301525060e0830135828111156129c057600080fd5b6129cc8a8286016127e8565b60e08301525061010080840135838111156129e657600080fd5b6129f28b8287016127e8565b8284015250506101208084013583811115612a0c57600080fd5b612a188b8287016127e8565b8284015250506101408084013583811115612a3257600080fd5b612a3e8b8287016127e8565b9183019190915250610160838101359082015261018080840135908201526101a080840135908201526101c080840135908201526101e09150612a8282840161270e565b8282015280935050505092959194509250565b60008060408385031215612aa857600080fd5b8235612ab3816126f6565b91506020830135612ac3816126f6565b809150509250929050565b60208082526019908201527f466169724d696e743a20616c7265616479207374617274656400000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561189457611894612b05565b808202811582820484141761189457611894612b05565b600082612b6257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052600160045260246000fd5b8082018082111561189457611894612b05565b600060208284031215612ba257600080fd5b8151611bbd816126f6565b600060208284031215612bbf57600080fd5b5051919050565b600181811c90821680612bda57607f821691505b602082108103612bfa57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115612591576000816000526020600020601f850160051c81016020861015612c295750805b601f850160051c820191505b81811015612c4857828155600101612c35565b505050505050565b815167ffffffffffffffff811115612c6a57612c6a6127a8565b612c7e81612c788454612bc6565b84612c00565b602080601f831160018114612cb35760008415612c9b5750858301515b600019600386901b1c1916600185901b178555612c48565b600085815260208120601f198616915b82811015612ce257888601518255948401946001909101908401612cc3565b5085821015612d005787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81516001600160a01b0316815261016081016020830151612d3c60208401826001600160a01b03169052565b506040830151612d53604084018262ffffff169052565b506060830151612d68606084018260020b9052565b506080830151612d7d608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151612dc3828501826001600160a01b03169052565b505061014092830151919092015290565b60008060008060808587031215612dea57600080fd5b8451935060208501516001600160801b0381168114612e0857600080fd5b604086015160609096015194979096509250505056fea2646970667358221220008622ac145d9e8c37b8e4f1a6ea0adc48a273d0b20bb14ed3af1a0458af834964736f6c63430008180033a2646970667358221220d46449eb5f31c2b929dfc3fd9b8c437242c889f678faf4e97ea4c838f3249c6a64736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ae52bd54742bd12b4ecf15cc35161d75d8af7481000000000000000000000000b7f74a16565e8cff8b4ad8a60b68c9af9055d81c000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe880000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984
-----Decoded View---------------
Arg [0] : _feeTo (address): 0xAe52bd54742bD12b4eCF15CC35161d75d8Af7481
Arg [1] : _locker (address): 0xb7f74a16565E8CFf8b4AD8a60b68c9af9055d81c
Arg [2] : _positionManager (address): 0xC36442b4a4522E871399CD717aBDD847Ab11FE88
Arg [3] : _factory (address): 0x1F98431c8aD98523631AE4a59f267346ea31F984
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000ae52bd54742bd12b4ecf15cc35161d75d8af7481
Arg [1] : 000000000000000000000000b7f74a16565e8cff8b4ad8a60b68c9af9055d81c
Arg [2] : 000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe88
Arg [3] : 0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984
Deployed Bytecode Sourcemap
84048:11742:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84273:20;;;;;;;;;;-1:-1:-1;84273:20:0;;;;-1:-1:-1;;;;;84273:20:0;;;;;;-1:-1:-1;;;;;287:32:1;;;269:51;;257:2;242:18;84273:20:0;;;;;;;;84623:32;;;;;;;;;;;;;;;;;;;477:25:1;;;465:2;450:18;84623:32:0;331:177:1;94872:911:0;;;;;;;;;;-1:-1:-1;94872:911:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;84566:48::-;;;;;;;;;;;;;;;;84742:28;;;;;;;;;;;;;;;;87802:508;;;;;;;;;;-1:-1:-1;87802:508:0;;;;;:::i;:::-;;:::i;:::-;;85385:41;;;;;;;;;;-1:-1:-1;85385:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;2903:14:1;;2896:22;2878:41;;2866:2;2851:18;85385:41:0;2738:187:1;84709:26:0;;;;;;;;;;-1:-1:-1;84709:26:0;;;;-1:-1:-1;;;;;84709:26:0;;;90991:750;;;;;;;;;;-1:-1:-1;90991:750:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3114:103::-;;;;;;;;;;;;;:::i;84467:35::-;;;;;;;;;;;;;;;;84511:48;;;;;;;;;;;;;;;;87364:107;;;;;;;;;;-1:-1:-1;87364:107:0;;;;;:::i;:::-;;:::i;2473:87::-;;;;;;;;;;-1:-1:-1;2519:7:0;2546:6;-1:-1:-1;;;;;2546:6:0;2473:87;;86710:84;;;;;;;;;;-1:-1:-1;86710:84:0;;;;;:::i;:::-;;:::i;86599:103::-;;;;;;;;;;-1:-1:-1;86599:103:0;;;;;:::i;:::-;;:::i;92430:825::-;;;;;;;;;;-1:-1:-1;92430:825:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;84246:20::-;;;;;;;;;;;;;;;;94133:731;;;;;;;;;;-1:-1:-1;94133:731:0;;;;;:::i;:::-;;:::i;84819:41::-;;;;;;;;;;-1:-1:-1;84819:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;89463:1518;;;;;;:::i;:::-;;:::i;87134:111::-;;;;;;;;;;-1:-1:-1;87134:111:0;;;;;:::i;:::-;;:::i;88968:487::-;;;;;;;;;;-1:-1:-1;88968:487:0;;;;;:::i;:::-;;:::i;86407:184::-;;;;;;;;;;-1:-1:-1;86407:184:0;;;;;:::i;:::-;;:::i;87010:116::-;;;;;;;;;;-1:-1:-1;87010:116:0;;;;;:::i;:::-;;:::i;87253:103::-;;;;;;;;;;-1:-1:-1;87253:103:0;;;;;:::i;:::-;;:::i;93263:860::-;;;;;;;;;;-1:-1:-1;93263:860:0;;;;;:::i;:::-;;:::i;86894:108::-;;;;;;;;;;-1:-1:-1;86894:108:0;;;;;:::i;:::-;;:::i;87479:287::-;;;;;;;;;;-1:-1:-1;87479:287:0;;;;;:::i;:::-;;:::i;91749:673::-;;;;;;;;;;-1:-1:-1;91749:673:0;;;;;:::i;:::-;;:::i;86229:170::-;;;;;;;;;;-1:-1:-1;86229:170:0;;;;;:::i;:::-;;:::i;84779:31::-;;;;;;;;;;;;;;;84427:33;;;;;;;;;;;;;;;;3372:201;;;;;;;;;;-1:-1:-1;3372:201:0;;;;;:::i;:::-;;:::i;86802:84::-;;;;;;;;;;-1:-1:-1;86802:84:0;;;;;:::i;:::-;;:::i;84662:38::-;;;;;;;;;;;;;;;;88354:570;;;;;;;;;;-1:-1:-1;88354:570:0;;;;;:::i;:::-;;:::i;94872:911::-;-1:-1:-1;;;;;95107:33:0;;95046:7;95107:33;;;:20;:33;;;;;95015:29;;95046:7;;;95107:42;;:40;:42::i;:::-;95071:78;;95171:25;95164:3;:32;95160:100;;95219:29;95247:1;95219:25;:29;:::i;:::-;95213:35;;95160:100;95270:14;95287:11;95293:5;95287:3;:11;:::i;:::-;:15;;95301:1;95287:15;:::i;:::-;95270:32;;95313:41;95384:6;95357:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95357:34:0;;;;;;;;;;;;;;;;-1:-1:-1;95313:78:0;-1:-1:-1;95402:20:0;95454:5;95437:257;95466:3;95461:1;:8;95437:257;;95519:16;95554:84;95591:4;:46;;95636:1;95591:46;;;95631:1;95599:29;95627:1;95599:25;:29;:::i;:::-;:33;;;;:::i;:::-;-1:-1:-1;;;;;95554:33:0;;;;;;:20;:33;;;;;;:36;:84::i;:::-;95519:134;;;;;;;;:::i;:::-;;;;;;;;;;95491:162;;;;;;;;95519:134;;;;;;;95491:162;;-1:-1:-1;;;;;95491:162:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;:11;;95503:12;;95491:25;;;;;;:::i;:::-;;;;;;:162;;;;95668:14;;;;;:::i;:::-;;;;95471:3;;;;;:::i;:::-;;;;95437:257;;;-1:-1:-1;95726:11:0;;95739:25;;-1:-1:-1;94872:911:0;;-1:-1:-1;;;;;;;94872:911:0:o;87802:508::-;87892:10;87882:21;;;;:9;:21;;;;;;;;87874:52;;;;-1:-1:-1;;;87874:52:0;;;;;;;:::i;:::-;;;;;;;;;87937:15;:32;;;;;;;-1:-1:-1;87937:32:0;;;;;;;;-1:-1:-1;;;;;;87937:32:0;87958:10;87937:32;;;87983:11;;-1:-1:-1;;;;;87983:11:0;:25;87980:323;;88049:11;;88042:44;;-1:-1:-1;;;88042:44:0;;88080:4;88042:44;;;269:51:1;88024:15:0;;-1:-1:-1;;;;;88049:11:0;;88042:29;;242:18:1;;88042:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88024:62;;88119:1;88104:12;;:16;:43;;;;;88135:12;;88124:7;:23;;88104:43;88101:191;;;88217:11;;88245:12;;88167:109;;-1:-1:-1;;;;;88217:11:0;;88230:13;;88167:27;:109::i;:::-;88009:294;87980:323;87802:508;:::o;90991:750::-;91085:19;;:::i;:::-;91122:39;91200:13;91122:93;;91233:500;;;;;;;;91268:11;-1:-1:-1;;;;;91268:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;91233:500:0;;;;;91324:11;-1:-1:-1;;;;;91233:500:0;;;;;91363:11;-1:-1:-1;;;;;91363:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91415:11;-1:-1:-1;;;;;91415:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91476:11;-1:-1:-1;;;;;91476:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91541:11;-1:-1:-1;;;;;91541:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91599:11;-1:-1:-1;;;;;91599:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91652:11;-1:-1:-1;;;;;91652:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91700:11;-1:-1:-1;;;;;91700:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91233:500;;;;91226:507;90991:750;-1:-1:-1;;;90991:750:0:o;3114:103::-;2359:13;:11;:13::i;:::-;3179:30:::1;3206:1;3179:18;:30::i;:::-;3114:103::o:0;87364:107::-;2359:13;:11;:13::i;:::-;87437:11:::1;:26:::0;;-1:-1:-1;;;;;;87437:26:0::1;-1:-1:-1::0;;;;;87437:26:0;;;::::1;::::0;;;::::1;::::0;;87364:107::o;86710:84::-;2359:13;:11;:13::i;:::-;86772:5:::1;:14:::0;86710:84::o;86599:103::-;2359:13;:11;:13::i;:::-;86670:10:::1;:24:::0;86599:103::o;92430:825::-;-1:-1:-1;;;;;92639:24:0;;92586:7;92639:24;;;:18;:24;;;;;92563:21;;92586:7;;;92639:33;;:31;:33::i;:::-;92611:61;;92694:17;92687:3;:24;92683:84;;92734:21;92754:1;92734:17;:21;:::i;:::-;92728:27;;92683:84;92777:14;92794:11;92800:5;92794:3;:11;:::i;:::-;:15;;92808:1;92794:15;:::i;:::-;92777:32;;92820:33;92875:6;92856:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;92820:62:0;-1:-1:-1;92893:20:0;92945:5;92928:247;92957:3;92952:1;:8;92928:247;;93010:124;93042:8;93051:67;93079:4;:38;;93116:1;93079:38;;;93111:1;93087:21;93107:1;93087:17;:21;:::i;:::-;:25;;;;:::i;:::-;-1:-1:-1;;;;;93051:24:0;;;;;;:18;:24;;;;;;:27;:67::i;:::-;93042:77;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;93042:77:0;93010:13;:124::i;:::-;92982:11;92994:12;92982:25;;;;;;;;:::i;:::-;;;;;;:152;;;;93149:14;;;;;:::i;:::-;;;;92962:3;;;;;:::i;:::-;;;;92928:247;;94133:731;94320:15;:22;94249:21;;94272:7;;94359:17;;;94355:70;;94399:14;94412:1;94399:10;:14;:::i;:::-;94393:20;;94355:70;94435:14;94452:11;94458:5;94452:3;:11;:::i;:::-;:15;;94466:1;94452:15;:::i;:::-;94435:32;;94478:33;94533:6;94514:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;94478:62:0;-1:-1:-1;94551:20:0;94603:5;94586:218;94615:3;94610:1;:8;94586:218;;94668:95;94700:15;94716:4;:31;;94746:1;94716:31;;;94741:1;94724:14;94737:1;94724:10;:14;:::i;:::-;:18;;;;:::i;94668:95::-;94640:11;94652:12;94640:25;;;;;;;;:::i;:::-;;;;;;:123;;;;94778:14;;;;;:::i;:::-;;;;94620:3;;;;;:::i;:::-;;;;94586:218;;;-1:-1:-1;94822:11:0;;94835:10;;-1:-1:-1;94133:731:0;;-1:-1:-1;;;;;;94133:731:0:o;89463:1518::-;89661:12;36804:21;:19;:21::i;:::-;89708:13:::1;::::0;89685:20:::1;::::0;::::1;:36:::0;89753:11:::1;::::0;-1:-1:-1;;;;;89753:11:0::1;89732:18;::::0;::::1;:32:::0;89795:10:::1;::::0;89775:17:::1;::::0;::::1;:30:::0;89836:10:::1;::::0;89816:17:::1;::::0;::::1;:30:::0;89901:14:::1;::::0;89879:18;;:36:::1;::::0;::::1;::::0;:76:::1;;-1:-1:-1::0;89941:14:0::1;::::0;89919:18;;:36:::1;;89879:76;89857:139;;;::::0;-1:-1:-1;;;89857:139:0;;12116:2:1;89857:139:0::1;::::0;::::1;12098:21:1::0;12155:2;12135:18;;;12128:30;12194:28;12174:18;;;12167:56;12240:18;;89857:139:0::1;11914:350:1::0;89857:139:0::1;90036:12;;90015:6;:17;;;:33;;:70;;;;;90073:12;;90052:6;:17;;;:33;;90015:70;90007:107;;;::::0;-1:-1:-1;;;90007:107:0;;12471:2:1;90007:107:0::1;::::0;::::1;12453:21:1::0;12510:2;12490:18;;;12483:30;12549:26;12529:18;;;12522:54;12593:18;;90007:107:0::1;12269:348:1::0;90007:107:0::1;90159:21;::::0;;::::1;::::0;-1:-1:-1;;;;;90149:32:0::1;;::::0;;;:9:::1;:32;::::0;;;::::1;;:67:::0;::::1;;;-1:-1:-1::0;90195:20:0::1;::::0;;::::1;::::0;-1:-1:-1;;;;;90185:31:0::1;;::::0;;;:9:::1;:31:::0;;;;;;;::::1;;90149:67;90127:166;;;::::0;-1:-1:-1;;;90127:166:0;;12824:2:1;90127:166:0::1;::::0;::::1;12806:21:1::0;12863:2;12843:18;;;12836:30;12902:34;12882:18;;;12875:62;-1:-1:-1;;;12953:18:1;;;12946:47;13010:19;;90127:166:0::1;12622:413:1::0;90127:166:0::1;90308:5;::::0;-1:-1:-1;;;;;90308:5:0::1;:19:::0;;::::1;::::0;:32:::1;;;90339:1;90331:5;;:9;90308:32;90304:242;;;90378:5;;90365:9;:18;;90357:49;;;::::0;-1:-1:-1;;;90357:49:0;;13242:2:1;90357:49:0::1;::::0;::::1;13224:21:1::0;13281:2;13261:18;;;13254:30;-1:-1:-1;;;13300:18:1;;;13293:48;13358:18;;90357:49:0::1;13040:342:1::0;90357:49:0::1;90448:5;::::0;90440:41:::1;::::0;90422:12:::1;::::0;-1:-1:-1;;;;;90448:5:0::1;::::0;90467:9:::1;::::0;90422:12;90440:41;90422:12;90440:41;90467:9;90448:5;90440:41:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90421:60;;;90506:7;90498:36;;;::::0;-1:-1:-1;;;90498:36:0;;13799:2:1;90498:36:0::1;::::0;::::1;13781:21:1::0;13838:2;13818:18;;;13811:30;-1:-1:-1;;;13857:18:1;;;13850:46;13913:18;;90498:36:0::1;13597:340:1::0;90498:36:0::1;90342:204;90304:242;90556:39;90598:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;90642:126:0::1;::::0;-1:-1:-1;;;90642:126:0;;90556:75;;-1:-1:-1;;;;;;90642:22:0;::::1;::::0;::::1;::::0;:126:::1;::::0;90679:6:::1;::::0;90700:8;;90723:13;;90751:6;;90642:126:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;90817:8:0::1;:19:::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;90817:19:0;;;;;;::::1;::::0;;-1:-1:-1;;;;;;90817:19:0::1;-1:-1:-1::0;;;;;90817:19:0;::::1;;::::0;;90885:15;;90817:19;;-1:-1:-1;90817:19:0;;90847:58:::1;::::0;-1:-1:-1;90885:19:0::1;::::0;-1:-1:-1;90885:19:0::1;:::i;:::-;-1:-1:-1::0;;;;;90847:33:0;::::1;;::::0;;;:18:::1;:33;::::0;;;;;:37:::1;:58::i;:::-;-1:-1:-1::0;;;;;;90916:15:0;::::1;;::::0;;;:9:::1;:15;::::0;;;;;;:22;;-1:-1:-1;;90916:22:0::1;90934:4;90916:22;::::0;;90956:17;::::1;::::0;::::1;::::0;90971:1:::1;477:25:1::0;;465:2;450:18;;331:177;90956:17:0::1;;;;;;;;89674:1307;36848:20:::0;36242:1;37368:22;;37185:213;36848:20;89463:1518;;;;;:::o;87134:111::-;2359:13;:11;:13::i;:::-;87209:12:::1;:28:::0;87134:111::o;88968:487::-;89071:10;89061:21;;;;:9;:21;;;;;;;;89053:52;;;;-1:-1:-1;;;89053:52:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;89116:29:0;;;;;;:20;:29;;;;;:72;;89167:10;89116:36;:72::i;:::-;-1:-1:-1;89235:101:0;;;;;;;;-1:-1:-1;;;;;89235:101:0;;;;;89283:1;89235:101;;;;;;;;;;;;89319:15;89235:101;;;;;;89199:16;:148;;;;;;;;-1:-1:-1;89199:148:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;89199:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;89409:23;;89358:89;;89409:27;;;:::i;:::-;89379:10;89358:32;;;;:20;:32;;;;;;:36;:89::i;:::-;;88968:487;;:::o;86407:184::-;2359:13;:11;:13::i;:::-;86508:14:::1;:32:::0;;;;86551:14:::1;:32:::0;86407:184::o;87010:116::-;2359:13;:11;:13::i;:::-;87088::::1;:30:::0;87010:116::o;87253:103::-;2359:13;:11;:13::i;:::-;87324:10:::1;:24:::0;87253:103::o;93263:860::-;-1:-1:-1;;;;;93481:26:0;;93420:7;93481:26;;;:20;:26;;;;;93397:21;;93420:7;;;93481:35;;:33;:35::i;:::-;93445:71;;93538:25;93531:3;:32;93527:100;;93586:29;93614:1;93586:25;:29;:::i;:::-;93580:35;;93527:100;93637:14;93654:11;93660:5;93654:3;:11;:::i;:::-;:15;;93668:1;93654:15;:::i;:::-;93637:32;;93680:33;93735:6;93716:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;93680:62:0;-1:-1:-1;93753:20:0;93805:5;93788:247;93817:3;93812:1;:8;93788:247;;93870:124;93902:77;93932:4;:46;;93977:1;93932:46;;;93972:1;93940:29;93968:1;93940:25;:29;:::i;:::-;:33;;;;:::i;:::-;-1:-1:-1;;;;;93902:26:0;;;;;;:20;:26;;;;;;:29;:77::i;93870:124::-;93842:11;93854:12;93842:25;;;;;;;;:::i;:::-;;;;;;:152;;;;94009:14;;;;;:::i;:::-;;;;93822:3;;;;;:::i;:::-;;;;93788:247;;86894:108;2359:13;:11;:13::i;:::-;86968:11:::1;:26:::0;;-1:-1:-1;;;;;;86968:26:0::1;-1:-1:-1::0;;;;;86968:26:0;;;::::1;::::0;;;::::1;::::0;;86894:108::o;87479:287::-;2359:13;:11;:13::i;:::-;87592:35:::1;::::0;-1:-1:-1;;;87592:35:0;;87621:4:::1;87592:35;::::0;::::1;269:51:1::0;87575:14:0::1;::::0;-1:-1:-1;;;;;87592:20:0;::::1;::::0;::::1;::::0;242:18:1;;87592:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87575:52;;87638:120;87688:2;87692:7;87711:12;87702:6;:21;:45;;87741:6;87638:27;:120::i;87702:45::-;87726:12;87638:27;:120::i;:::-;87564:202;87479:287:::0;;;:::o;91749:673::-;91920:8;:15;91861:21;;91884:7;;91913:22;;91909:80;;91958:8;:15;:19;;91976:1;;91958:19;:::i;:::-;91952:25;;91909:80;91999:14;92016:11;92022:5;92016:3;:11;:::i;:::-;:15;;92030:1;92016:15;:::i;:::-;91999:32;;92042:33;92097:6;92078:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;92042:62:0;-1:-1:-1;92115:20:0;92167:5;92150:216;92179:3;92174:1;:8;92150:216;;92232:93;92264:8;92273:4;:36;;92308:1;92273:36;;;92281:8;:15;92303:1;;92281:19;;92299:1;;92281:19;:::i;92232:93::-;92204:11;92216:12;92204:25;;;;;;;;:::i;:::-;;;;;;:121;;;;92340:14;;;;;:::i;:::-;;;;92184:3;;;;;:::i;:::-;;;;92150:216;;;-1:-1:-1;;92398:8:0;:15;92384:11;;92398:15;;-1:-1:-1;91749:673:0;-1:-1:-1;;;;;91749:673:0:o;86229:170::-;2359:13;:11;:13::i;:::-;86324:12:::1;:28:::0;;;;86363:12:::1;:28:::0;86229:170::o;3372:201::-;2359:13;:11;:13::i;:::-;-1:-1:-1;;;;;3461:22:0;::::1;3453:73;;;::::0;-1:-1:-1;;;3453:73:0;;17766:2:1;3453:73:0::1;::::0;::::1;17748:21:1::0;17805:2;17785:18;;;17778:30;17844:34;17824:18;;;17817:62;-1:-1:-1;;;17895:18:1;;;17888:36;17941:19;;3453:73:0::1;17564:402:1::0;3453:73:0::1;3537:28;3556:8;3537:18;:28::i;86802:84::-:0;2359:13;:11;:13::i;:::-;86864:5:::1;:14:::0;;-1:-1:-1;;;;;;86864:14:0::1;-1:-1:-1::0;;;;;86864:14:0;;;::::1;::::0;;;::::1;::::0;;86802:84::o;88354:570::-;88454:10;88444:21;;;;:9;:21;;;;;;;;88436:52;;;;-1:-1:-1;;;88436:52:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;88503:29:0;;;;;;:20;:29;;;;;:50;;88542:10;88503:38;:50::i;:::-;88499:159;;-1:-1:-1;;;;;88569:29:0;;;;;;:20;:29;;;;;:77;;88621:10;88569:33;:77::i;:::-;;88499:159;88704:101;;;;;;;;-1:-1:-1;;;;;88704:101:0;;;;;88752:1;88704:101;;;;;;;;;;;;88788:15;88704:101;;;;;;88668:16;:148;;;;;;;-1:-1:-1;88668:148:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;88668:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88878:23;88827:89;;88878:27;;;:::i;81212:114::-;81272:7;81299:19;81307:3;74013:18;;73930:109;81299:19;81292:26;81212:114;-1:-1:-1;;81212:114:0:o;81680:137::-;81751:7;81786:22;81790:3;81802:5;81786:3;:22::i;82950:361::-;83145:45;;;-1:-1:-1;;;;;18163:32:1;;;83145:45:0;;;18145:51:1;18212:18;;;;18205:34;;;83145:45:0;;;;;;;;;;18118:18:1;;;;83145:45:0;;;;;;;-1:-1:-1;;;;;83145:45:0;-1:-1:-1;;;83145:45:0;;;83134:57;;-1:-1:-1;;;;83134:10:0;;;;:57;;83145:45;83134:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83098:93;;;;83210:7;:57;;;;-1:-1:-1;83222:11:0;;:16;;:44;;;83253:4;83242:24;;;;;;;;;;;;:::i;:::-;83202:101;;;;-1:-1:-1;;;83202:101:0;;18744:2:1;83202:101:0;;;18726:21:1;18783:2;18763:18;;;18756:30;18822:33;18802:18;;;18795:61;18873:18;;83202:101:0;18542:355:1;83202:101:0;83020:291;;82950:361;;;:::o;2638:132::-;2519:7;2546:6;-1:-1:-1;;;;;2546:6:0;942:10;2702:23;2694:68;;;;-1:-1:-1;;;2694:68:0;;19104:2:1;2694:68:0;;;19086:21:1;;;19123:18;;;19116:30;19182:34;19162:18;;;19155:62;19234:18;;2694:68:0;18902:356:1;3733:191:0;3807:16;3826:6;;-1:-1:-1;;;;;3843:17:0;;;-1:-1:-1;;;;;;3843:17:0;;;;;;3876:40;;3826:6;;;;;;;3876:40;;3807:16;3876:40;3796:128;3733:191;:::o;36884:293::-;36286:1;37018:7;;:19;37010:63;;;;-1:-1:-1;;;37010:63:0;;19465:2:1;37010:63:0;;;19447:21:1;19504:2;19484:18;;;19477:30;19543:33;19523:18;;;19516:61;19594:18;;37010:63:0;19263:355:1;37010:63:0;36286:1;37151:7;:18;36884:293::o;80450:131::-;80517:4;80541:32;80546:3;80566:5;80541:4;:32::i;78216:158::-;78289:4;78313:53;78321:3;-1:-1:-1;;;;;78341:23:0;;78313:7;:53::i;78460:167::-;-1:-1:-1;;;;;78594:23:0;;78540:4;73812:19;;;:12;;;:19;;;;;;:24;;78564:55;73715:129;77888:152;77958:4;77982:50;77987:3;-1:-1:-1;;;;;78007:23:0;;77982:4;:50::i;74393:120::-;74460:7;74487:3;:11;;74499:5;74487:18;;;;;;;;:::i;:::-;;;;;;;;;74480:25;;74393:120;;;;:::o;71619:414::-;71682:4;73812:19;;;:12;;;:19;;;;;;71699:327;;-1:-1:-1;71742:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;71925:18;;71903:19;;;:12;;;:19;;;;;;:40;;;;71958:11;;71699:327;-1:-1:-1;72009:5:0;72002:12;;72209:1420;72275:4;72414:19;;;:12;;;:19;;;;;;72450:15;;72446:1176;;72825:21;72849:14;72862:1;72849:10;:14;:::i;:::-;72898:18;;72825:38;;-1:-1:-1;72878:17:0;;72898:22;;72919:1;;72898:22;:::i;:::-;72878:42;;72954:13;72941:9;:26;72937:405;;72988:17;73008:3;:11;;73020:9;73008:22;;;;;;;;:::i;:::-;;;;;;;;;72988:42;;73162:9;73133:3;:11;;73145:13;73133:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;73247:23;;;:12;;;:23;;;;;:36;;;72937:405;73423:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;73518:3;:12;;:19;73531:5;73518:19;;;;;;;;;;;73511:26;;;73561:4;73554:11;;;;;;;72446:1176;73605:5;73598:12;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;513:118:1:-;599:5;592:13;585:21;578:5;575:32;565:60;;621:1;618;611:12;636:131;-1:-1:-1;;;;;711:31:1;;701:42;;691:70;;757:1;754;747:12;772:134;840:20;;869:31;840:20;869:31;:::i;:::-;772:134;;;:::o;911:519::-;994:6;1002;1010;1018;1071:3;1059:9;1050:7;1046:23;1042:33;1039:53;;;1088:1;1085;1078:12;1039:53;1127:9;1114:23;1146:28;1168:5;1146:28;:::i;:::-;1193:5;-1:-1:-1;1250:2:1;1235:18;;1222:32;1263:33;1222:32;1263:33;:::i;:::-;911:519;;1315:7;;-1:-1:-1;;;;1369:2:1;1354:18;;1341:32;;1420:2;1405:18;1392:32;;911:519::o;1435:1046::-;1710:2;1762:21;;;1832:13;;1735:18;;;1854:22;;;1681:4;;1710:2;1895;;1913:18;;;;1950:4;1977:17;;;1681:4;2022:388;2036:6;2033:1;2030:13;2022:388;;;2095:13;;2137:9;;-1:-1:-1;;;;;2133:35:1;2121:48;;2209:11;;;2203:18;2189:12;;;2182:40;2262:11;;;2256:18;2242:12;;;2235:40;2315:11;;2309:18;2295:12;;;2288:40;2357:4;2348:14;;;;2385:15;;;;2165:1;2051:9;2022:388;;;2026:3;;;;2427;2419:11;;;;;2468:6;2461:4;2450:9;2446:20;2439:36;1435:1046;;;;;:::o;2486:247::-;2545:6;2598:2;2586:9;2577:7;2573:23;2569:32;2566:52;;;2614:1;2611;2604:12;2566:52;2653:9;2640:23;2672:31;2697:5;2672:31;:::i;2930:638::-;3023:1;3019;3014:3;3010:11;3006:19;3064:2;3056:5;3050:12;3046:21;3041:3;3034:34;3129:2;3121:4;3114:5;3110:16;3104:23;3100:32;3093:4;3088:3;3084:14;3077:56;;3182:4;3175:5;3171:16;3165:23;3158:4;3153:3;3149:14;3142:47;3238:4;3231:5;3227:16;3221:23;3214:4;3209:3;3205:14;3198:47;3294:4;3287:5;3283:16;3277:23;3270:4;3265:3;3261:14;3254:47;3350:4;3343:5;3339:16;3333:23;3326:4;3321:3;3317:14;3310:47;3406:4;3399:5;3395:16;3389:23;3382:4;3377:3;3373:14;3366:47;3462:4;3455:5;3451:16;3445:23;3438:4;3433:3;3429:14;3422:47;3488:6;3555:2;3548:5;3544:14;3538:21;3531:29;3524:37;3519:2;3514:3;3510:12;3503:59;;2930:638;;:::o;3573:262::-;3767:3;3752:19;;3780:49;3756:9;3811:6;3780:49;:::i;3840:180::-;3899:6;3952:2;3940:9;3931:7;3927:23;3923:32;3920:52;;;3968:1;3965;3958:12;3920:52;-1:-1:-1;3991:23:1;;3840:180;-1:-1:-1;3840:180:1:o;4025:797::-;4303:2;4315:21;;;4385:13;;4288:18;;;4407:22;;;4255:4;;4482;;4460:2;4445:18;;;4509:17;;;4255:4;4554:197;4568:6;4565:1;4562:13;4554:197;;;4617:50;4663:3;4654:6;4648:13;4617:50;:::i;:::-;4696:6;4687:16;;;;;4726:15;;;;4590:1;4583:9;4554:197;;;-1:-1:-1;;;4802:4:1;4787:20;;;;4780:36;;;;-1:-1:-1;4768:3:1;4025:797;-1:-1:-1;;4025:797:1:o;4827:377::-;4901:6;4909;4917;4970:2;4958:9;4949:7;4945:23;4941:32;4938:52;;;4986:1;4983;4976:12;4938:52;5025:9;5012:23;5044:28;5066:5;5044:28;:::i;:::-;5091:5;5143:2;5128:18;;5115:32;;-1:-1:-1;5194:2:1;5179:18;;;5166:32;;4827:377;-1:-1:-1;;;4827:377:1:o;5209:127::-;5270:10;5265:3;5261:20;5258:1;5251:31;5301:4;5298:1;5291:15;5325:4;5322:1;5315:15;5341:250;5408:2;5402:9;5450:6;5438:19;;5487:18;5472:34;;5508:22;;;5469:62;5466:88;;;5534:18;;:::i;:::-;5570:2;5563:22;5341:250;:::o;5596:719::-;5639:5;5692:3;5685:4;5677:6;5673:17;5669:27;5659:55;;5710:1;5707;5700:12;5659:55;5746:6;5733:20;5772:18;5809:2;5805;5802:10;5799:36;;;5815:18;;:::i;:::-;5890:2;5884:9;5858:2;5944:13;;-1:-1:-1;;5940:22:1;;;5964:2;5936:31;5932:40;5920:53;;;5988:18;;;6008:22;;;5985:46;5982:72;;;6034:18;;:::i;:::-;6074:10;6070:2;6063:22;6109:2;6101:6;6094:18;6155:3;6148:4;6143:2;6135:6;6131:15;6127:26;6124:35;6121:55;;;6172:1;6169;6162:12;6121:55;6236:2;6229:4;6221:6;6217:17;6210:4;6202:6;6198:17;6185:54;6283:1;6276:4;6271:2;6263:6;6259:15;6255:26;6248:37;6303:6;6294:15;;;;;;5596:719;;;;:::o;6320:2846::-;6440:6;6448;6456;6509:2;6497:9;6488:7;6484:23;6480:32;6477:52;;;6525:1;6522;6515:12;6477:52;6564:9;6551:23;6583:31;6608:5;6583:31;:::i;:::-;6633:5;-1:-1:-1;6690:2:1;6675:18;;6662:32;6738:8;6725:22;;6713:35;;6703:63;;6762:1;6759;6752:12;6703:63;6785:7;-1:-1:-1;6843:2:1;6828:18;;6815:32;6866:18;6896:14;;;6893:34;;;6923:1;6920;6913:12;6893:34;6946:22;;;;7002:6;6984:16;;;6980:29;6977:49;;;7022:1;7019;7012:12;6977:49;7050:17;;:::i;:::-;7105:2;7092:16;7083:7;7076:33;7143:31;7170:2;7166;7162:11;7143:31;:::i;:::-;7138:2;7129:7;7125:16;7118:57;7209:31;7236:2;7232;7228:11;7209:31;:::i;:::-;7204:2;7195:7;7191:16;7184:57;7287:2;7283;7279:11;7266:25;7316:2;7306:8;7303:16;7300:36;;;7332:1;7329;7322:12;7300:36;7370:45;7407:7;7396:8;7392:2;7388:17;7370:45;:::i;:::-;7365:2;7356:7;7352:16;7345:71;;7462:3;7458:2;7454:12;7441:26;7492:2;7482:8;7479:16;7476:36;;;7508:1;7505;7498:12;7476:36;7547:45;7584:7;7573:8;7569:2;7565:17;7547:45;:::i;:::-;7541:3;7532:7;7528:17;7521:72;;7639:3;7635:2;7631:12;7618:26;7669:2;7659:8;7656:16;7653:36;;;7685:1;7682;7675:12;7653:36;7724:45;7761:7;7750:8;7746:2;7742:17;7724:45;:::i;:::-;7718:3;7709:7;7705:17;7698:72;;7816:3;7812:2;7808:12;7795:26;7846:2;7836:8;7833:16;7830:36;;;7862:1;7859;7852:12;7830:36;7901:45;7938:7;7927:8;7923:2;7919:17;7901:45;:::i;:::-;7895:3;7886:7;7882:17;7875:72;;7993:3;7989:2;7985:12;7972:26;8023:2;8013:8;8010:16;8007:36;;;8039:1;8036;8029:12;8007:36;8078:45;8115:7;8104:8;8100:2;8096:17;8078:45;:::i;:::-;8072:3;8063:7;8059:17;8052:72;;8143:3;8192:2;8188;8184:11;8171:25;8221:2;8211:8;8208:16;8205:36;;;8237:1;8234;8227:12;8205:36;8275:45;8312:7;8301:8;8297:2;8293:17;8275:45;:::i;:::-;8270:2;8261:7;8257:16;8250:71;;;8340:3;8389:2;8385;8381:11;8368:25;8418:2;8408:8;8405:16;8402:36;;;8434:1;8431;8424:12;8402:36;8472:45;8509:7;8498:8;8494:2;8490:17;8472:45;:::i;:::-;8467:2;8458:7;8454:16;8447:71;;;8537:3;8586:2;8582;8578:11;8565:25;8615:2;8605:8;8602:16;8599:36;;;8631:1;8628;8621:12;8599:36;8669:45;8706:7;8695:8;8691:2;8687:17;8669:45;:::i;:::-;8651:16;;;8644:71;;;;-1:-1:-1;8734:3:1;8784:11;;;8771:25;8753:16;;;8746:51;8816:3;8866:11;;;8853:25;8835:16;;;8828:51;8898:3;8948:11;;;8935:25;8917:16;;;8910:51;8980:3;9030:11;;;9017:25;8999:16;;;8992:51;9063:3;;-1:-1:-1;9101:32:1;9120:12;;;9101:32;:::i;:::-;9095:3;9086:7;9082:17;9075:59;9153:7;9143:17;;;;;6320:2846;;;;;:::o;9171:315::-;9239:6;9247;9300:2;9288:9;9279:7;9275:23;9271:32;9268:52;;;9316:1;9313;9306:12;9268:52;9355:9;9342:23;9374:31;9399:5;9374:31;:::i;:::-;9424:5;9476:2;9461:18;;;;9448:32;;-1:-1:-1;;;9171:315:1:o;9491:248::-;9559:6;9567;9620:2;9608:9;9599:7;9595:23;9591:32;9588:52;;;9636:1;9633;9626:12;9588:52;-1:-1:-1;;9659:23:1;;;9729:2;9714:18;;;9701:32;;-1:-1:-1;9491:248:1:o;9744:456::-;9821:6;9829;9837;9890:2;9878:9;9869:7;9865:23;9861:32;9858:52;;;9906:1;9903;9896:12;9858:52;9945:9;9932:23;9964:31;9989:5;9964:31;:::i;:::-;10014:5;-1:-1:-1;10071:2:1;10056:18;;10043:32;10084:33;10043:32;10084:33;:::i;:::-;9744:456;;10136:7;;-1:-1:-1;;;10190:2:1;10175:18;;;;10162:32;;9744:456::o;10205:127::-;10266:10;10261:3;10257:20;10254:1;10247:31;10297:4;10294:1;10287:15;10321:4;10318:1;10311:15;10337:128;10404:9;;;10425:11;;;10422:37;;;10439:18;;:::i;10470:125::-;10535:9;;;10556:10;;;10553:36;;;10569:18;;:::i;10600:127::-;10661:10;10656:3;10652:20;10649:1;10642:31;10692:4;10689:1;10682:15;10716:4;10713:1;10706:15;10732:135;10771:3;10792:17;;;10789:43;;10812:18;;:::i;:::-;-1:-1:-1;10859:1:1;10848:13;;10732:135::o;10872:342::-;11074:2;11056:21;;;11113:2;11093:18;;;11086:30;-1:-1:-1;;;11147:2:1;11132:18;;11125:48;11205:2;11190:18;;10872:342::o;11219:184::-;11289:6;11342:2;11330:9;11321:7;11317:23;11313:32;11310:52;;;11358:1;11355;11348:12;11310:52;-1:-1:-1;11381:16:1;;11219:184;-1:-1:-1;11219:184:1:o;11408:251::-;11478:6;11531:2;11519:9;11510:7;11506:23;11502:32;11499:52;;;11547:1;11544;11537:12;11499:52;11579:9;11573:16;11598:31;11623:5;11598:31;:::i;11664:245::-;11731:6;11784:2;11772:9;11763:7;11759:23;11755:32;11752:52;;;11800:1;11797;11790:12;11752:52;11832:9;11826:16;11851:28;11873:5;11851:28;:::i;13942:250::-;14027:1;14037:113;14051:6;14048:1;14045:13;14037:113;;;14127:11;;;14121:18;14108:11;;;14101:39;14073:2;14066:10;14037:113;;;-1:-1:-1;;14184:1:1;14166:16;;14159:27;13942:250::o;14197:271::-;14239:3;14277:5;14271:12;14304:6;14299:3;14292:19;14320:76;14389:6;14382:4;14377:3;14373:14;14366:4;14359:5;14355:16;14320:76;:::i;:::-;14450:2;14429:15;-1:-1:-1;;14425:29:1;14416:39;;;;14457:4;14412:50;;14197:271;-1:-1:-1;;14197:271:1:o;14473:2896::-;14735:4;14781:1;14777;14772:3;14768:11;14764:19;14822:2;14814:6;14810:15;14799:9;14792:34;14874:8;14866:6;14862:21;14857:2;14846:9;14842:18;14835:49;14932:2;14924:6;14920:15;14915:2;14904:9;14900:18;14893:43;;14972:3;14967:2;14956:9;14952:18;14945:31;15019:6;15013:13;15007:3;14996:9;14992:19;14985:42;15074:2;15066:6;15062:15;15056:22;15087:53;15135:3;15124:9;15120:19;15106:12;-1:-1:-1;;;;;80:31:1;68:44;;14:104;15087:53;-1:-1:-1;15189:2:1;15177:15;;15171:22;-1:-1:-1;;;;;80:31:1;15252:3;15237:19;;68:44;15306:2;15294:15;;15288:22;15329:6;15366:3;15351:19;;15344:31;;;15398:54;15447:3;15432:19;;15288:22;15398:54;:::i;:::-;15384:68;;15501:3;15493:6;15489:16;15483:23;15529:3;15525:8;15552:3;15619:2;15607:9;15599:6;15595:22;15591:31;15586:2;15575:9;15571:18;15564:59;15646:41;15680:6;15664:14;15646:41;:::i;:::-;15632:55;;15736:3;15728:6;15724:16;15718:23;15696:45;;15760:3;15827:2;15815:9;15807:6;15803:22;15799:31;15794:2;15783:9;15779:18;15772:59;15854:41;15888:6;15872:14;15854:41;:::i;:::-;15840:55;;15944:3;15936:6;15932:16;15926:23;15904:45;;15968:3;16035:2;16023:9;16015:6;16011:22;16007:31;16002:2;15991:9;15987:18;15980:59;16062:41;16096:6;16080:14;16062:41;:::i;:::-;16048:55;;16152:3;16144:6;16140:16;16134:23;16112:45;;16176:3;16243:2;16231:9;16223:6;16219:22;16215:31;16210:2;16199:9;16195:18;16188:59;16270:41;16304:6;16288:14;16270:41;:::i;:::-;16256:55;;16360:2;16352:6;16348:15;16342:22;16320:44;;16383:3;16373:13;;16450:2;16438:9;16430:6;16426:22;16422:31;16417:2;16406:9;16402:18;16395:59;16477:41;16511:6;16495:14;16477:41;:::i;:::-;16463:55;;16567:2;16559:6;16555:15;16549:22;16527:44;;16590:3;16580:13;;16657:2;16645:9;16637:6;16633:22;16629:31;16624:2;16613:9;16609:18;16602:59;16684:41;16718:6;16702:14;16684:41;:::i;:::-;16670:55;;16774:2;16766:6;16762:15;16756:22;16734:44;;16798:3;16787:14;;16866:2;16854:9;16846:6;16842:22;16838:31;16832:3;16821:9;16817:19;16810:60;16893:41;16927:6;16911:14;16893:41;:::i;:::-;16960:15;;;16954:22;16996:3;17015:19;;;17008:32;;;;17082:15;;;17076:22;17056:18;;;17049:50;;;;17142:15;;;17136:22;17130:3;17115:19;;17108:51;17202:16;;17196:23;17190:3;17175:19;;17168:52;17258:16;;17252:23;-1:-1:-1;;;;;80:31:1;;17335:3;17320:19;;68:44;16960:15;;-1:-1:-1;17284:56:1;;-1:-1:-1;;14:104:1;17284:56;-1:-1:-1;17357:6:1;14473:2896;-1:-1:-1;;;;;;14473:2896:1:o;18250:287::-;18379:3;18417:6;18411:13;18433:66;18492:6;18487:3;18480:4;18472:6;18468:17;18433:66;:::i;:::-;18515:16;;;;;18250:287;-1:-1:-1;;18250:287:1:o;19623:127::-;19684:10;19679:3;19675:20;19672:1;19665:31;19715:4;19712:1;19705:15;19739:4;19736:1;19729:15
Swarm Source
ipfs://d46449eb5f31c2b929dfc3fd9b8c437242c889f678faf4e97ea4c838f3249c6a
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 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.