More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 32,944 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Harvest Pool | 10191392 | 370 days ago | IN | 0 CRO | 0.68338915 | ||||
Harvest Pool | 3316167 | 820 days ago | IN | 0 CRO | 0.86699256 | ||||
Harvest Pool | 2322144 | 888 days ago | IN | 0 CRO | 0.742975 | ||||
Harvest Pool | 2315787 | 889 days ago | IN | 0 CRO | 0.72089 | ||||
Harvest Pool | 2284622 | 891 days ago | IN | 0 CRO | 0.655475 | ||||
Harvest Pool | 2284612 | 891 days ago | IN | 0 CRO | 0.87089 | ||||
Harvest Pool | 2260485 | 893 days ago | IN | 0 CRO | 0.742975 | ||||
Harvest Pool | 2248054 | 894 days ago | IN | 0 CRO | 0.79589 | ||||
Harvest Pool | 2235524 | 895 days ago | IN | 0 CRO | 0.667975 | ||||
Harvest Pool | 2235519 | 895 days ago | IN | 0 CRO | 0.87089 | ||||
Harvest Pool | 2160967 | 900 days ago | IN | 0 CRO | 0.87089 | ||||
Harvest Pool | 2127238 | 902 days ago | IN | 0 CRO | 0.79589 | ||||
Harvest Pool | 2113472 | 903 days ago | IN | 0 CRO | 0.667975 | ||||
Harvest Pool | 2113471 | 903 days ago | IN | 0 CRO | 0.79589 | ||||
Harvest Pool | 2107243 | 904 days ago | IN | 0 CRO | 0.72089 | ||||
Harvest Pool | 2038350 | 908 days ago | IN | 0 CRO | 0.730475 | ||||
Harvest Pool | 2020073 | 910 days ago | IN | 0 CRO | 0.85839 | ||||
Harvest Pool | 1996581 | 911 days ago | IN | 0 CRO | 0.72089 | ||||
Harvest Pool | 1996560 | 911 days ago | IN | 0 CRO | 0.805475 | ||||
Harvest Pool | 1961464 | 914 days ago | IN | 0 CRO | 0.87089 | ||||
Harvest Pool | 1946676 | 915 days ago | IN | 0 CRO | 0.87089 | ||||
Harvest Pool | 1850789 | 921 days ago | IN | 0 CRO | 0.70839 | ||||
Harvest Pool | 1831448 | 923 days ago | IN | 0 CRO | 0.85839 | ||||
Harvest Pool | 1826980 | 923 days ago | IN | 0 CRO | 0.85839 | ||||
Harvest Pool | 1819366 | 923 days ago | IN | 0 CRO | 0.87089 |
Loading...
Loading
Contract Name:
IGO
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at cronoscan.com on 2022-01-17 */ // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 () internal { _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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } pragma solidity >=0.6.0 <0.8.0; /** * @dev These functions deal with verification of Merkle trees (hash trees), */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { // Hash(current element of the proof + current computed hash) computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } } // Check if the computed hash (root) is equal to the provided root return computedHash == root; } } // File @openzeppelin/contracts/math/[email protected] pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File @openzeppelin/contracts/token/ERC20/[email protected] pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); } // File @openzeppelin/contracts/utils/[email protected] pragma solidity >=0.6.2 <0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/[email protected] pragma solidity >=0.6.0 <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 SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } 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' // solhint-disable-next-line max-line-length 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)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @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"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File @openzeppelin/contracts/utils/[email protected] pragma solidity >=0.6.0 <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 GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File @openzeppelin/contracts/access/[email protected] pragma solidity >=0.6.0 <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 () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File @openzeppelin/contracts/token/ERC20/[email protected] pragma solidity >=0.6.0 <0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 value {ERC20} uses, unless {_setupDecimals} is * called. * * 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 returns (uint8) { return _decimals; } /** * @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: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, 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}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), 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}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 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) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(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) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is 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: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, 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: * * - `to` 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 = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(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); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(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 Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal virtual { _decimals = decimals_; } /** * @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 to 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 { } } pragma solidity 0.6.12; /** @title IIGO. * @notice It is an interface for IGO.sol */ interface IIGO { /** * @notice It allows users to deposit LP tokens to pool * @param _amount: the number of LP token used (18 decimals) * @param _pid: poolId */ function depositPool(uint256 _amount, uint8 _pid, bytes32[] calldata _proof) external; /** * @notice It allows users to harvest from pool * @param _pid: poolId */ function harvestPool(uint8 _pid) external; /** * @notice Set new merkleroot for whitelisting * @param _pid: poolId * @param _merkleRoot: the root */ function setWhitelist(uint8 _pid, bytes32 _merkleRoot) external; /** * @notice It allows the admin to withdraw funds * @param _lpAmount: the number of LP token to withdraw (18 decimals) * @param _offerAmount: the number of offering amount to withdraw * @dev This function is only callable by admin. */ function finalWithdraw(uint256 _lpAmount, uint256 _offerAmount) external; /** * @notice It sets parameters for pool * @param _offeringAmountPool: offering amount (in tokens) * @param _raisingAmountPool: raising amount (in LP tokens) * @param _limitPerUserInLP: limit per user (in LP tokens) * @param _hasTax: if the pool has a tax * @param _hasMaxOverflow: if there is a limit on total deposit to the pool * @param _maxOverflow: max value of ratio of total amount / raising amount * @param _pid: poolId * @dev This function is only callable by admin. */ function setPool( uint256 _offeringAmountPool, uint256 _raisingAmountPool, uint256 _limitPerUserInLP, bool _hasTax, bool _hasMaxOverflow, uint256 _maxOverflow, bool _hasWhitelist, uint8 _pid ) external; /** * @notice It updates campaign id for the IGO. * @param _campaignId: the campaignId for the IGO * @dev This function is only callable by admin. */ function updateCampaignId( uint256 _campaignId ) external; /** * @notice It returns the pool information * @param _pid: poolId * @return raisingAmountPool: amount of LP tokens raised (in LP tokens) * @return offeringAmountPool: amount of tokens offered for the pool (in offeringTokens) * @return limitPerUserInLP; // limit of tokens per user (if 0, it is ignored) * @return hasTax: tax on the overflow (if any, it works with _calculateTaxOverflow) * @return totalAmountPool: total amount pool deposited (in LP tokens) * @return sumTaxesOverflow: total taxes collected (starts at 0, increases with each harvest if overflow) * @return hasMaxOverflow: if there is a limit on total deposit to the pool * @return maxOverflow: max value of ratio of total amount / raising amount; min 100; 100 is 1x, 250 is 2.5x * @return hasWhitelist: whether the pool implements whitelisting * @return merkleRoot: whitelist data in merkle tree format */ function viewPoolInformation(uint256 _pid) external view returns ( uint256, uint256, uint256, bool, uint256, uint256, bool, uint256, bool, bytes32 ); /** * @notice It returns the tax overflow rate calculated for a pool * @dev 100,000 means 0.1(10%)/ 1 means 0.000001(0.0001%)/ 1,000,000 means 1(100%) * @param _pid: poolId * @return It returns the tax percentage */ function viewPoolTaxRateOverflow(uint256 _pid) external view returns (uint256); /** * @notice External view function to see user information * @param _user: user address * @param _pids[]: array of pids */ function viewUserInfo(address _user, uint8[] calldata _pids) external view returns (uint256[] memory, bool[] memory); /** * @notice External view function to see user allocations for both pools * @param _user: user address * @param _pids[]: array of pids */ function viewUserAllocationPools(address _user, uint8[] calldata _pids) external view returns (uint256[] memory); /** * @notice External view function to see user offering and refunding amounts for both pools * @param _user: user address * @param _pids: array of pids */ function viewUserOfferingAndRefundingAmountsForPools(address _user, uint8[] calldata _pids) external view returns (uint256[3][] memory); /** * @notice Check if the address is whitelisted in basic pool * @param _user: user address * @param _pid: poolId * @param _proof: the proof (containing sibling hashes on the branch from the leaf to the root of the tree) * @return true if whitelisted, false otherwise */ function isWhitelisted(address _user, uint8 _pid, bytes32[] calldata _proof) external view returns (bool); /** * @notice Check if overflow * @param _pid: poolId * @return */ function isMaxOverflowReached(uint8 _pid) external view returns (bool); /** * @notice Check the remaining amount that can be deposited (in LP token) * @param _pid: poolId * @return */ function viewRemainingDepositAmount(uint8 _pid) external view returns (uint256); } contract IGO is IIGO, ReentrancyGuard, Ownable { using SafeMath for uint256; using SafeERC20 for IERC20; // The LP token used IERC20 public lpToken; // The offering token IERC20 public offeringToken; // Number of pools uint8 public constant numberPools = 2; // The block number when IGO starts uint256 public startBlock; // The block number when IGO ends uint256 public endBlock; // The campaignId for the IGO uint256 public campaignId; // Array of PoolCharacteristics of size numberPools PoolCharacteristics[numberPools] private _poolInformation; // It maps the address to pool id to UserInfo mapping(address => mapping(uint8 => UserInfo)) private _userInfo; // Struct that contains each pool characteristics struct PoolCharacteristics { uint256 raisingAmountPool; // amount of tokens raised for the pool (in LP tokens) uint256 offeringAmountPool; // amount of tokens offered for the pool (in offeringTokens) uint256 limitPerUserInLP; // limit of tokens per user (if 0, it is ignored) bool hasTax; // tax on the overflow (if any, it works with _calculateTaxOverflow) uint256 totalAmountPool; // total amount pool deposited (in LP tokens) uint256 sumTaxesOverflow; // total taxes collected (starts at 0, increases with each harvest if overflow) bool hasMaxOverflow; // if there is a limit on total deposit to the pool uint256 maxOverflow; // max value of ratio of total amount / raising amount; min 100; 100 is 1x, 250 is 2.5x bool hasWhitelist; // whether the pool implements whitelisting bytes32 merkleRoot; // whitelist data in merkle tree format } // Struct that contains each user information for both pools struct UserInfo { uint256 amountPool; // How many tokens the user has provided for pool bool claimedPool; // Whether the user has claimed (default: false) for pool } // Admin withdraw events event AdminWithdraw(uint256 amountLP, uint256 amountOfferingToken); // Admin recovers token event AdminTokenRecovery(address tokenAddress, uint256 amountTokens); // Deposit event event Deposit(address indexed user, uint8 indexed pid, uint256 amount); // Harvest event event Harvest(address indexed user, uint8 indexed pid, uint256 offeringAmount, uint256 excessAmount); // Event for new start & end blocks event NewStartAndEndBlocks(uint256 startBlock, uint256 endBlock); // Event with campaignId for IGO event CampaignIdSet(uint256 campaignId); // Event when parameters are set for one of the pools event PoolParametersSet( uint8 indexed pid, uint256 offeringAmountPool, uint256 raisingAmountPool, uint256 limitPerUserInLP, bool hasTax, bool hasMaxOverflow, uint256 maxOverflow, bool hasWhitelist ); // Event when setting whitelist for a pool event WhitelistSet(uint8 indexed pid, bytes32 merkleRoot); // Modifier to prevent contracts to participate modifier notContract() { require(!_isContract(msg.sender), "contract not allowed"); require(msg.sender == tx.origin, "proxy contract not allowed"); _; } /** * @notice It initializes the contract (for proxy patterns) * @dev It can only be called once. * @param _lpToken: the LP token used * @param _offeringToken: the token that is offered for the IGO * @param _startBlock: the start block for the IGO * @param _endBlock: the end block for the IGO * @param _adminAddress: the admin address for handling tokens */ constructor( IERC20 _lpToken, IERC20 _offeringToken, uint256 _startBlock, uint256 _endBlock, address _adminAddress ) public { require(_lpToken.totalSupply() >= 0); require(_offeringToken.totalSupply() >= 0); require(_lpToken != _offeringToken, "Tokens must be be different"); lpToken = _lpToken; offeringToken = _offeringToken; startBlock = _startBlock; endBlock = _endBlock; transferOwnership(_adminAddress); } /** * @notice It allows users to deposit LP tokens to pool * @param _amount: the number of LP token used (18 decimals) * @param _pid: pool id * @param _proof: the proof (containing sibling hashes on the branch from the leaf to the root of the tree) */ function depositPool(uint256 _amount, uint8 _pid, bytes32[] calldata _proof) external override nonReentrant notContract { // Checks whether the pool id is valid require(_pid < numberPools, "Pool does not exist"); // Checks that pool was set require( _poolInformation[_pid].offeringAmountPool > 0 && _poolInformation[_pid].raisingAmountPool > 0, "Pool not set" ); // Checks whitelisting if the pool requires it if (_poolInformation[_pid].hasWhitelist) { require(_isWhitelisted(msg.sender, _pid, _proof), "User is not whitelisted"); } // If the pool has max overflow, it should be within the limit if (_poolInformation[_pid].hasMaxOverflow) { require(_isMaxOverflowReached(_pid) == false, "Pool cap reached"); require(viewRemainingDepositAmount(_pid) >= _amount, "Deposit amount above the overflow limit"); } // Checks whether the block number is not too early require(block.number > startBlock, "Too early"); // Checks whether the block number is not too late require(block.number < endBlock, "Too late"); // Checks that the amount deposited is not inferior to 0 require(_amount > 0, "Amount must be > 0"); // Transfers funds to this contract lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); // Update the user status _userInfo[msg.sender][_pid].amountPool = _userInfo[msg.sender][_pid].amountPool.add(_amount); // Check if the pool has a limit per user if (_poolInformation[_pid].limitPerUserInLP > 0) { // Checks whether the limit has been reached require( _userInfo[msg.sender][_pid].amountPool <= _poolInformation[_pid].limitPerUserInLP, "New amount above user limit" ); } // Updates the totalAmount for pool _poolInformation[_pid].totalAmountPool = _poolInformation[_pid].totalAmountPool.add(_amount); emit Deposit(msg.sender, _pid, _amount); } /** * @notice It allows users to harvest from pool * @param _pid: pool id */ function harvestPool(uint8 _pid) external override nonReentrant notContract { // Checks whether it is too early to harvest require(block.number > endBlock, "Too early to harvest"); // Checks whether pool id is valid require(_pid < numberPools, "Pool does not exist"); // Checks whether the user has participated require(_userInfo[msg.sender][_pid].amountPool > 0, "Did not participate"); // Checks whether the user has already harvested require(!_userInfo[msg.sender][_pid].claimedPool, "Has harvested"); // Updates the harvest status _userInfo[msg.sender][_pid].claimedPool = true; // Initialize the variables for offering, refunding user amounts, and tax amount uint256 offeringTokenAmount; uint256 refundingTokenAmount; uint256 userTaxOverflow; (offeringTokenAmount, refundingTokenAmount, userTaxOverflow) = _calculateOfferingAndRefundingAmountsPool( msg.sender, _pid ); // Increment the sumTaxesOverflow if (userTaxOverflow > 0) { _poolInformation[_pid].sumTaxesOverflow = _poolInformation[_pid].sumTaxesOverflow.add(userTaxOverflow); } // Transfer these tokens back to the user if quantity > 0 if (offeringTokenAmount > 0) { offeringToken.safeTransfer(address(msg.sender), offeringTokenAmount); } if (refundingTokenAmount > 0) { lpToken.safeTransfer(address(msg.sender), refundingTokenAmount); } emit Harvest(msg.sender, _pid, offeringTokenAmount, refundingTokenAmount); } /** * @notice Set new merkleroot for whitelisting * @param _pid: poolId * @param _merkleRoot: the root */ function setWhitelist(uint8 _pid, bytes32 _merkleRoot) external override onlyOwner { require(block.number < startBlock, "IGO has started"); require(_pid < numberPools, "Pool does not exist"); _poolInformation[_pid].merkleRoot = _merkleRoot; emit WhitelistSet(_pid, _merkleRoot); } /** * @notice It allows the admin to withdraw funds * @param _lpAmount: the number of LP token to withdraw (18 decimals) * @param _offerAmount: the number of offering amount to withdraw * @dev This function is only callable by admin. */ function finalWithdraw(uint256 _lpAmount, uint256 _offerAmount) external override onlyOwner { require(_lpAmount <= lpToken.balanceOf(address(this)), "Not enough LP tokens"); require(_offerAmount <= offeringToken.balanceOf(address(this)), "Not enough offering token"); if (_lpAmount > 0) { lpToken.safeTransfer(address(msg.sender), _lpAmount); } if (_offerAmount > 0) { offeringToken.safeTransfer(address(msg.sender), _offerAmount); } emit AdminWithdraw(_lpAmount, _offerAmount); } /** * @notice It allows the admin to recover wrong tokens sent to the contract * @param _tokenAddress: the address of the token to withdraw (18 decimals) * @param _tokenAmount: the number of token amount to withdraw * @dev This function is only callable by admin. */ function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require(_tokenAddress != address(lpToken), "Cannot be LP token"); require(_tokenAddress != address(offeringToken), "Cannot be offering token"); require(_tokenAmount <= IERC20(_tokenAddress).balanceOf(address(this)), "Cannot recover more than balance"); IERC20(_tokenAddress).safeTransfer(address(msg.sender), _tokenAmount); emit AdminTokenRecovery(_tokenAddress, _tokenAmount); } /** * @notice It sets parameters for pool * @param _offeringAmountPool: offering amount (in tokens) * @param _raisingAmountPool: raising amount (in LP tokens) * @param _limitPerUserInLP: limit per user (in LP tokens) * @param _hasTax: if the pool has a tax * @param _hasMaxOverflow: if there is a limit on total deposit to the pool * @param _maxOverflow: max value of ratio of total amount / raising amount * @param _pid: pool id * @dev This function is only callable by admin. */ function setPool( uint256 _offeringAmountPool, uint256 _raisingAmountPool, uint256 _limitPerUserInLP, bool _hasTax, bool _hasMaxOverflow, uint256 _maxOverflow, bool _hasWhitelist, uint8 _pid ) external override onlyOwner { require(block.number < startBlock, "IGO has started"); require(_pid < numberPools, "Pool does not exist"); if (_hasMaxOverflow) { require(_maxOverflow >= 100, "Max Overflow at least 100"); } _poolInformation[_pid].offeringAmountPool = _offeringAmountPool; _poolInformation[_pid].raisingAmountPool = _raisingAmountPool; _poolInformation[_pid].limitPerUserInLP = _limitPerUserInLP; _poolInformation[_pid].hasTax = _hasTax; _poolInformation[_pid].hasMaxOverflow = _hasMaxOverflow; _poolInformation[_pid].maxOverflow = _maxOverflow; _poolInformation[_pid].hasWhitelist = _hasWhitelist; emit PoolParametersSet(_pid, _offeringAmountPool, _raisingAmountPool, _limitPerUserInLP, _hasTax, _hasMaxOverflow, _maxOverflow, _hasWhitelist); } /** * @notice It updates campaignId for the IGO. * @param _campaignId: the campaignId for the IGO * @dev This function is only callable by admin. */ function updateCampaignId( uint256 _campaignId ) external override onlyOwner { require(block.number < endBlock, "IGO has ended"); campaignId = _campaignId; emit CampaignIdSet(campaignId); } /** * @notice It allows the admin to update start and end blocks * @param _startBlock: the new start block * @param _endBlock: the new end block * @dev This function is only callable by admin. */ function updateStartAndEndBlocks(uint256 _startBlock, uint256 _endBlock) external onlyOwner { require(block.number < startBlock, "IGO has started"); require(_startBlock < _endBlock, "New startBlock must be lower than new endBlock"); require(block.number < _startBlock, "New startBlock must be higher than current block"); startBlock = _startBlock; endBlock = _endBlock; emit NewStartAndEndBlocks(_startBlock, _endBlock); } /** * @notice It returns the pool information * @param _pid: poolId * @return raisingAmountPool: amount of LP tokens raised (in LP tokens) * @return offeringAmountPool: amount of tokens offered for the pool (in offeringTokens) * @return limitPerUserInLP; // limit of tokens per user (if 0, it is ignored) * @return hasTax: tax on the overflow (if any, it works with _calculateTaxOverflow) * @return totalAmountPool: total amount pool deposited (in LP tokens) * @return sumTaxesOverflow: total taxes collected (starts at 0, increases with each harvest if overflow) * @return hasMaxOverflow: if there is a limit on total deposit to the pool * @return maxOverflow: max value of ratio of total amount / raising amount; min 100; 100 is 1x, 250 is 2.5x * @return hasWhitelist: whether the pool implements whitelisting * @return merkleRoot: whitelist data in merkle tree format */ function viewPoolInformation(uint256 _pid) external view override returns ( uint256, uint256, uint256, bool, uint256, uint256, bool, uint256, bool, bytes32 ) { PoolCharacteristics memory _poolInfo = _poolInformation[_pid]; return ( _poolInfo.raisingAmountPool, _poolInfo.offeringAmountPool, _poolInfo.limitPerUserInLP, _poolInfo.hasTax, _poolInfo.totalAmountPool, _poolInfo.sumTaxesOverflow, _poolInfo.hasMaxOverflow, _poolInfo.maxOverflow, _poolInfo.hasWhitelist, _poolInfo.merkleRoot ); } /** * @notice It returns the tax overflow rate calculated for a pool * @dev 100,000,000,000 means 0.1 (10%) / 1 means 0.0000000000001 (0.0000001%) / 1,000,000,000,000 means 1 (100%) * @param _pid: poolId * @return It returns the tax percentage */ function viewPoolTaxRateOverflow(uint256 _pid) external view override returns (uint256) { if (!_poolInformation[_pid].hasTax) { return 0; } else { return _calculateTaxOverflow(_poolInformation[_pid].totalAmountPool, _poolInformation[_pid].raisingAmountPool); } } /** * @notice External view function to see user allocations for both pools * @param _user: user address * @param _pids[]: array of pids * @return */ function viewUserAllocationPools(address _user, uint8[] calldata _pids) external view override returns (uint256[] memory) { uint256[] memory allocationPools = new uint256[](_pids.length); for (uint8 i = 0; i < _pids.length; i++) { allocationPools[i] = _getUserAllocationPool(_user, _pids[i]); } return allocationPools; } /** * @notice Check if the address is whitelisted in basic pool * @param _user: user address * @param _pid: poolId * @param _proof: the proof (containing sibling hashes on the branch from the leaf to the root of the tree) * @return true if whitelisted, false otherwise */ function isWhitelisted(address _user, uint8 _pid, bytes32[] calldata _proof) external view override returns (bool) { return _isWhitelisted(_user, _pid, _proof); } /** * @notice External view function to see user information * @param _user: user address * @param _pids[]: array of pids */ function viewUserInfo(address _user, uint8[] calldata _pids) external view override returns (uint256[] memory, bool[] memory) { uint256[] memory amountPools = new uint256[](_pids.length); bool[] memory statusPools = new bool[](_pids.length); for (uint8 i = 0; i < _pids.length; i++) { amountPools[i] = _userInfo[_user][_pids[i]].amountPool; statusPools[i] = _userInfo[_user][_pids[i]].claimedPool; } return (amountPools, statusPools); } /** * @notice External view function to see user offering and refunding amounts for both pools * @param _user: user address * @param _pids: array of pids */ function viewUserOfferingAndRefundingAmountsForPools(address _user, uint8[] calldata _pids) external view override returns (uint256[3][] memory) { uint256[3][] memory amountPools = new uint256[3][](_pids.length); for (uint8 i = 0; i < _pids.length; i++) { uint256 userOfferingAmountPool; uint256 userRefundingAmountPool; uint256 userTaxAmountPool; if (_poolInformation[_pids[i]].raisingAmountPool > 0) { ( userOfferingAmountPool, userRefundingAmountPool, userTaxAmountPool ) = _calculateOfferingAndRefundingAmountsPool(_user, _pids[i]); } amountPools[i] = [userOfferingAmountPool, userRefundingAmountPool, userTaxAmountPool]; } return amountPools; } /** * @notice Check the remaining amount that can be deposited (in LP token) * @param _pid: poolId * @return */ function viewRemainingDepositAmount(uint8 _pid) public view override returns (uint256) { require(_pid < numberPools, "Pool does not exist"); PoolCharacteristics memory poolInfo = _poolInformation[_pid]; if (!poolInfo.hasMaxOverflow) { return uint256(-1).sub(poolInfo.raisingAmountPool); } return (poolInfo.maxOverflow.mul(poolInfo.raisingAmountPool).div(100)).sub(poolInfo.totalAmountPool); } /** * @notice Check if the maximum deposit is reached * @param _pid: poolId * @return true if the limit has been reached */ function isMaxOverflowReached(uint8 _pid) external view override returns (bool) { return _isMaxOverflowReached(_pid); } /** * @notice It calculates the tax overflow given the raisingAmountPool and the totalAmountPool. * @dev 100,000,000,000 means 0.1 (10%) / 1 means 0.0000000000001 (0.0000001%) / 1,000,000,000,000 means 1 (100%) * @return It returns the tax percentage */ function _calculateTaxOverflow(uint256 _totalAmountPool, uint256 _raisingAmountPool) internal pure returns (uint256) { uint256 ratioOverflow = _totalAmountPool.div(_raisingAmountPool); if (ratioOverflow >= 200) { return 2000000000; // 0.2% } else if (ratioOverflow >= 100) { return 2500000000; // 0.25% } else if (ratioOverflow >= 50) { return 3000000000; // 0.3% } else if (ratioOverflow >= 25) { return 5000000000; // 0.5% } else { return 10000000000; // 1% } } /** * @notice It calculates the offering amount for a user and the number of LP tokens to transfer back. * @param _user: user address * @param _pid: pool id * @return {uint256, uint256, uint256} It returns the offering amount, the refunding amount (in LP tokens), * and the tax (if any, else 0) */ function _calculateOfferingAndRefundingAmountsPool(address _user, uint8 _pid) internal view returns ( uint256, uint256, uint256 ) { uint256 userOfferingAmount; uint256 userRefundingAmount; uint256 taxAmount; if (_poolInformation[_pid].totalAmountPool > _poolInformation[_pid].raisingAmountPool) { // Calculate allocation for the user uint256 allocation = _getUserAllocationPool(_user, _pid); // Calculate the offering amount for the user based on the offeringAmount for the pool userOfferingAmount = _poolInformation[_pid].offeringAmountPool.mul(allocation).div(1e12); // Calculate the payAmount uint256 payAmount = _poolInformation[_pid].raisingAmountPool.mul(allocation).div(1e12); // Calculate the pre-tax refunding amount userRefundingAmount = _userInfo[_user][_pid].amountPool.sub(payAmount); // Retrieve the tax rate if (_poolInformation[_pid].hasTax) { uint256 taxOverflow = _calculateTaxOverflow( _poolInformation[_pid].totalAmountPool, _poolInformation[_pid].raisingAmountPool ); // Calculate the final taxAmount taxAmount = userRefundingAmount.mul(taxOverflow).div(1e12); // Adjust the refunding amount userRefundingAmount = userRefundingAmount.sub(taxAmount); } } else { userRefundingAmount = 0; taxAmount = 0; // _userInfo[_user] / (raisingAmount / offeringAmount) userOfferingAmount = _userInfo[_user][_pid].amountPool.mul(_poolInformation[_pid].offeringAmountPool).div( _poolInformation[_pid].raisingAmountPool ); } return (userOfferingAmount, userRefundingAmount, taxAmount); } /** * @notice It checks if the account belongs to the merkle tree, i.e. whitelisted * @param _account: user address * @param _proof: the proof (containing sibling hashes on the branch from the leaf to the root of the tree) * @return if the user is in the tree, i.e. whitelisted */ function _isWhitelisted(address _account, uint8 _pid, bytes32[] memory _proof) internal view returns (bool) { require(_pid < numberPools, "Pool does not exist"); if (!_poolInformation[_pid].hasWhitelist) { return true; } require(_poolInformation[_pid].merkleRoot != 0, "Whitelist is not set"); // Verify the merkle proof bytes32 leaf = keccak256(abi.encodePacked(_account)); return MerkleProof.verify(_proof, _poolInformation[_pid].merkleRoot, leaf); } /** * @notice It returns the user allocation for pool * @dev 100,000,000,000 means 0.1 (10%) / 1 means 0.0000000000001 (0.0000001%) / 1,000,000,000,000 means 1 (100%) * @param _user: user address * @param _pid: pool id * @return it returns the user's share of pool */ function _getUserAllocationPool(address _user, uint8 _pid) internal view returns (uint256) { if (_poolInformation[_pid].totalAmountPool > 0) { return _userInfo[_user][_pid].amountPool.mul(1e18).div(_poolInformation[_pid].totalAmountPool.mul(1e6)); } else { return 0; } } /** * @notice Check if the maximum deposit is reached * @param _pid: pool id * @return true if the limit is reached. Otherwise, false */ function _isMaxOverflowReached(uint8 _pid) internal view returns (bool) { require(_pid < numberPools, "Pool does not exist"); // No limit is set if (!_poolInformation[_pid].hasMaxOverflow) { return false; } // Get the ratio, time 100, due to maxOverflow definition uint256 ratioOverflow = (_poolInformation[_pid].totalAmountPool).mul(100).div(_poolInformation[_pid].raisingAmountPool); return ratioOverflow >= _poolInformation[_pid].maxOverflow; } /** * @notice Check if an address is a contract */ function _isContract(address _addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(_addr) } return size > 0; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"contract IERC20","name":"_offeringToken","type":"address"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_endBlock","type":"uint256"},{"internalType":"address","name":"_adminAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"}],"name":"AdminTokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amountLP","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfferingToken","type":"uint256"}],"name":"AdminWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"campaignId","type":"uint256"}],"name":"CampaignIdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint8","name":"pid","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint8","name":"pid","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"offeringAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"excessAmount","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewStartAndEndBlocks","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":"uint8","name":"pid","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"offeringAmountPool","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"raisingAmountPool","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"limitPerUserInLP","type":"uint256"},{"indexed":false,"internalType":"bool","name":"hasTax","type":"bool"},{"indexed":false,"internalType":"bool","name":"hasMaxOverflow","type":"bool"},{"indexed":false,"internalType":"uint256","name":"maxOverflow","type":"uint256"},{"indexed":false,"internalType":"bool","name":"hasWhitelist","type":"bool"}],"name":"PoolParametersSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"pid","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"WhitelistSet","type":"event"},{"inputs":[],"name":"campaignId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"depositPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpAmount","type":"uint256"},{"internalType":"uint256","name":"_offerAmount","type":"uint256"}],"name":"finalWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"}],"name":"harvestPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"}],"name":"isMaxOverflowReached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberPools","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"offeringToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverWrongTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offeringAmountPool","type":"uint256"},{"internalType":"uint256","name":"_raisingAmountPool","type":"uint256"},{"internalType":"uint256","name":"_limitPerUserInLP","type":"uint256"},{"internalType":"bool","name":"_hasTax","type":"bool"},{"internalType":"bool","name":"_hasMaxOverflow","type":"bool"},{"internalType":"uint256","name":"_maxOverflow","type":"uint256"},{"internalType":"bool","name":"_hasWhitelist","type":"bool"},{"internalType":"uint8","name":"_pid","type":"uint8"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","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":"uint256","name":"_campaignId","type":"uint256"}],"name":"updateCampaignId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_endBlock","type":"uint256"}],"name":"updateStartAndEndBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"viewPoolInformation","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"viewPoolTaxRateOverflow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"}],"name":"viewRemainingDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8[]","name":"_pids","type":"uint8[]"}],"name":"viewUserAllocationPools","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8[]","name":"_pids","type":"uint8[]"}],"name":"viewUserInfo","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8[]","name":"_pids","type":"uint8[]"}],"name":"viewUserOfferingAndRefundingAmountsForPools","outputs":[{"internalType":"uint256[3][]","name":"","type":"uint256[3][]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620034a5380380620034a5833981810160405260a08110156200003757600080fd5b50805160208201516040830151606084015160809094015160016000908155939492939192916200006762000248565b600180546001600160a01b0319166001600160a01b0383169081179091556040519192509060009060008051602062003485833981519152908290a3506000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015620000e057600080fd5b505afa158015620000f5573d6000803e3d6000fd5b505050506040513d60208110156200010c57600080fd5b505110156200011a57600080fd5b6000846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200015657600080fd5b505afa1580156200016b573d6000803e3d6000fd5b505050506040513d60208110156200018257600080fd5b505110156200019057600080fd5b836001600160a01b0316856001600160a01b03161415620001f8576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e73206d75737420626520626520646966666572656e740000000000604482015290519081900360640190fd5b600280546001600160a01b038088166001600160a01b0319928316179092556003805492871692909116919091179055600483905560058290556200023d816200024c565b505050505062000366565b3390565b6200025662000248565b6001600160a01b03166200026962000357565b6001600160a01b031614620002c5576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166200030c5760405162461bcd60e51b81526004018080602001828103825260268152602001806200345f6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216906000805160206200348583398151915290600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031690565b6130e980620003766000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80638da5cb5b116100de578063b781360711610097578063f2fde38b11610071578063f2fde38b14610638578063f9a1dedb1461065e578063f9a6a1fd146106af578063f9cd5c121461073557610173565b8063b781360714610521578063c6b8358c14610529578063ca463ca41461054957610173565b80638da5cb5b146104305780638ed5b0fc146104385780639513997f146104405780639f1b524814610463578063add075e114610486578063b42392f11461050357610173565b806348cd4cb11161013057806348cd4cb1146102a25780634af3c9b7146102aa5780635fcbd285146103c1578063715018a6146103e557806377aef522146103ed578063795f46ac1461041357610173565b8063083c6323146101785780632374876c1461019257806337f859b8146101b45780633f138d4b146101d15780633f6500bf146101fd57806346ab91bf14610231575b600080fd5b610180610803565b60408051918252519081900360200190f35b6101b2600480360360208110156101a857600080fd5b503560ff16610809565b005b610180600480360360208110156101ca57600080fd5b5035610b87565b6101b2600480360360408110156101e757600080fd5b506001600160a01b038135169060200135610be4565b61021d6004803603602081101561021357600080fd5b503560ff16610e23565b604080519115158252519081900360200190f35b61024e6004803603602081101561024757600080fd5b5035610e2e565b604080519a8b5260208b0199909952898901979097529415156060890152608088019390935260a0870191909152151560c086015260e0850152151561010084015261012083015251908190036101400190f35b610180610f51565b610328600480360360408110156102c057600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156102ea57600080fd5b8201836020820111156102fc57600080fd5b803590602001918460208302840111600160201b8311171561031d57600080fd5b509092509050610f57565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561036c578181015183820152602001610354565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156103ab578181015183820152602001610393565b5050505090500194505050505060405180910390f35b6103c96110f1565b604080516001600160a01b039092168252519081900360200190f35b6101b2611100565b6101b26004803603604081101561040357600080fd5b5060ff81351690602001356111ac565b6101b26004803603602081101561042957600080fd5b50356112ff565b6103c96113e2565b6101806113f1565b6101b26004803603604081101561045657600080fd5b50803590602001356113f7565b6101b26004803603604081101561047957600080fd5b5080359060200135611566565b6101b26004803603606081101561049c57600080fd5b81359160ff60208201351691810190606081016040820135600160201b8111156104c557600080fd5b8201836020820111156104d757600080fd5b803590602001918460208302840111600160201b831117156104f857600080fd5b5090925090506117ce565b61050b611d66565b6040805160ff9092168252519081900360200190f35b6103c9611d6b565b6101806004803603602081101561053f57600080fd5b503560ff16611d7a565b6105c76004803603604081101561055f57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561058957600080fd5b82018360208201111561059b57600080fd5b803590602001918460208302840111600160201b831117156105bc57600080fd5b509092509050611ec4565b60405180806020018281038252838181518152602001915080516000925b8184101561062757602080850284010151606080838360005b838110156106165781810151838201526020016105fe565b5050505090500192600101926105e5565b925050509250505060405180910390f35b6101b26004803603602081101561064e57600080fd5b50356001600160a01b0316611fd5565b6101b2600480360361010081101561067557600080fd5b508035906020810135906040810135906060810135151590608081013515159060a08101359060c081013515159060e0013560ff166120d8565b61021d600480360360608110156106c557600080fd5b6001600160a01b038235169160ff60208201351691810190606081016040820135600160201b8111156106f757600080fd5b82018360208201111561070957600080fd5b803590602001918460208302840111600160201b8311171561072a57600080fd5b50909250905061238d565b6107b36004803603604081101561074b57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561077557600080fd5b82018360208201111561078757600080fd5b803590602001918460208302840111600160201b831117156107a857600080fd5b5090925090506123d6565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107ef5781810151838201526020016107d7565b505050509050019250505060405180910390f35b60055481565b60026000541415610861576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005561086f3361246f565b156108b8576040805162461bcd60e51b815260206004820152601460248201527318dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604482015290519081900360640190fd5b33321461090c576040805162461bcd60e51b815260206004820152601a60248201527f70726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000604482015290519081900360640190fd5b6005544311610959576040805162461bcd60e51b8152602060048201526014602482015273151bdbc819585c9b1e481d1bc81a185c9d995cdd60621b604482015290519081900360640190fd5b600260ff8216106109a7576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b336000908152601b6020908152604080832060ff85168452909152902054610a0c576040805162461bcd60e51b8152602060048201526013602482015272446964206e6f7420706172746963697061746560681b604482015290519081900360640190fd5b336000908152601b6020908152604080832060ff80861685529252909120600101541615610a71576040805162461bcd60e51b815260206004820152600d60248201526c12185cc81a185c9d995cdd1959609a1b604482015290519081900360640190fd5b336000818152601b6020908152604080832060ff8616845290915281206001908101805460ff191690911790559081908190610aad9085612475565b919450925090508015610b0057610ae48160078660ff1660028110610ace57fe5b600a02016005015461264490919063ffffffff16565b60078560ff1660028110610af457fe5b600a0201600501819055505b8215610b1d57600354610b1d906001600160a01b031633856126a7565b8115610b3a57600254610b3a906001600160a01b031633846126a7565b6040805184815260208101849052815160ff87169233927f1839f39a4e3eeee0272f5304923e2c487330fadc80f6df38384c8fdaf396580a929081900390910190a3505060016000555050565b600060078260028110610b9657fe5b600a02016003015460ff16610bad57506000610bdf565b610bdc60078360028110610bbd57fe5b600a02016004015460078460028110610bd257fe5b600a0201546126fe565b90505b919050565b610bec612770565b6001600160a01b0316610bfd6113e2565b6001600160a01b031614610c46576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6002546001600160a01b0383811691161415610c9e576040805162461bcd60e51b815260206004820152601260248201527121b0b73737ba103132902628103a37b5b2b760711b604482015290519081900360640190fd5b6003546001600160a01b0383811691161415610d01576040805162461bcd60e51b815260206004820152601860248201527f43616e6e6f74206265206f66666572696e6720746f6b656e0000000000000000604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610d4757600080fd5b505afa158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b5051811115610dc7576040805162461bcd60e51b815260206004820181905260248201527f43616e6e6f74207265636f766572206d6f7265207468616e2062616c616e6365604482015290519081900360640190fd5b610ddb6001600160a01b03831633836126a7565b604080516001600160a01b03841681526020810183905281517f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab78129929181900390910190a15050565b6000610bdc82612774565b600080600080600080600080600080610e45612efd565b60078c60028110610e5257fe5b600a0201604051806101400160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815260200160048201548152602001600582015481526020016006820160009054906101000a900460ff16151515158152602001600782015481526020016008820160009054906101000a900460ff161515151581526020016009820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e001518861010001518961012001519a509a509a509a509a509a509a509a509a509a50509193959799509193959799565b60045481565b606080808367ffffffffffffffff81118015610f7257600080fd5b50604051908082528060200260200182016040528015610f9c578160200160208202803683370190505b50905060608467ffffffffffffffff81118015610fb857600080fd5b50604051908082528060200260200182016040528015610fe2578160200160208202803683370190505b50905060005b60ff81168611156110e4576001600160a01b0388166000908152601b6020526040812090888860ff851681811061101b57fe5b9050602002013560ff1660ff1660ff16815260200190815260200160002060000154838260ff168151811061104c57fe5b602002602001018181525050601b6000896001600160a01b03166001600160a01b03168152602001908152602001600020600088888460ff1681811061108e57fe5b9050602002013560ff1660ff1660ff16815260200190815260200160002060010160009054906101000a900460ff16828260ff16815181106110cc57fe5b91151560209283029190910190910152600101610fe8565b5090969095509350505050565b6002546001600160a01b031681565b611108612770565b6001600160a01b03166111196113e2565b6001600160a01b031614611162576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6111b4612770565b6001600160a01b03166111c56113e2565b6001600160a01b03161461120e576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6004544310611256576040805162461bcd60e51b815260206004820152600f60248201526e1251d3c81a185cc81cdd185c9d1959608a1b604482015290519081900360640190fd5b600260ff8316106112a4576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b8060078360ff16600281106112b557fe5b600a0201600901819055508160ff167ffd91ec8ce9c48e69d6b6d618cc3102804bac2d28fd3b8ac26fc1fa887194e311826040518082815260200191505060405180910390a25050565b611307612770565b6001600160a01b03166113186113e2565b6001600160a01b031614611361576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b60055443106113a7576040805162461bcd60e51b815260206004820152600d60248201526c1251d3c81a185cc8195b991959609a1b604482015290519081900360640190fd5b60068190556040805182815290517fb3858839cb95bac816de879b29203046e91b49859f71499c319ce06688891cb99181900360200190a150565b6001546001600160a01b031690565b60065481565b6113ff612770565b6001600160a01b03166114106113e2565b6001600160a01b031614611459576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b60045443106114a1576040805162461bcd60e51b815260206004820152600f60248201526e1251d3c81a185cc81cdd185c9d1959608a1b604482015290519081900360640190fd5b8082106114df5760405162461bcd60e51b815260040180806020018281038252602e815260200180612fc5602e913960400191505060405180910390fd5b81431061151d5760405162461bcd60e51b81526004018080602001828103825260308152602001806130196030913960400191505060405180910390fd5b60048290556005819055604080518381526020810183905281517f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce06929181900390910190a15050565b61156e612770565b6001600160a01b031661157f6113e2565b6001600160a01b0316146115c8576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b600254604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561161357600080fd5b505afa158015611627573d6000803e3d6000fd5b505050506040513d602081101561163d57600080fd5b505182111561168a576040805162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768204c5020746f6b656e7360601b604482015290519081900360640190fd5b600354604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156116d557600080fd5b505afa1580156116e9573d6000803e3d6000fd5b505050506040513d60208110156116ff57600080fd5b5051811115611755576040805162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f756768206f66666572696e6720746f6b656e00000000000000604482015290519081900360640190fd5b811561177257600254611772906001600160a01b031633846126a7565b801561178f5760035461178f906001600160a01b031633836126a7565b604080518381526020810183905281517f94ebb62a252249c867ecb758d386f50a95be7e8df9e1c52917c9cf494327dd7d929181900390910190a15050565b60026000541415611826576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556118343361246f565b1561187d576040805162461bcd60e51b815260206004820152601460248201527318dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604482015290519081900360640190fd5b3332146118d1576040805162461bcd60e51b815260206004820152601a60248201527f70726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000604482015290519081900360640190fd5b600260ff84161061191f576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b600060078460ff166002811061193157fe5b600a02016001015411801561195a5750600060078460ff166002811061195357fe5b600a020154115b61199a576040805162461bcd60e51b815260206004820152600c60248201526b141bdbdb081b9bdd081cd95d60a21b604482015290519081900360640190fd5b60078360ff16600281106119aa57fe5b600a02016008015460ff1615611a49576119f8338484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061285592505050565b611a49576040805162461bcd60e51b815260206004820152601760248201527f55736572206973206e6f742077686974656c6973746564000000000000000000604482015290519081900360640190fd5b60078360ff1660028110611a5957fe5b600a02016006015460ff1615611afe57611a7283612774565b15611ab7576040805162461bcd60e51b815260206004820152601060248201526f141bdbdb0818d85c081c995858da195960821b604482015290519081900360640190fd5b83611ac184611d7a565b1015611afe5760405162461bcd60e51b8152600401808060200182810382526027815260200180612f786027913960400191505060405180910390fd5b6004544311611b40576040805162461bcd60e51b8152602060048201526009602482015268546f6f206561726c7960b81b604482015290519081900360640190fd5b6005544310611b81576040805162461bcd60e51b8152602060048201526008602482015267546f6f206c61746560c01b604482015290519081900360640190fd5b60008411611bcb576040805162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b604482015290519081900360640190fd5b600254611be3906001600160a01b031633308761298c565b336000908152601b6020908152604080832060ff87168452909152902054611c0b9085612644565b336000908152601b6020908152604080832060ff881680855292528220929092559060079060028110611c3a57fe5b600a0201600201541115611cd15760078360ff1660028110611c5857fe5b600a020160020154336000908152601b6020908152604080832060ff881684529091529020541115611cd1576040805162461bcd60e51b815260206004820152601b60248201527f4e657720616d6f756e742061626f76652075736572206c696d69740000000000604482015290519081900360640190fd5b611cfb8460078560ff1660028110611ce557fe5b600a02016004015461264490919063ffffffff16565b60078460ff1660028110611d0b57fe5b600a0201600401819055508260ff16336001600160a01b03167fe6ea2883ec66613be5cdd4954e8c4919bdb7982e6e2d907011bc051bfcde7fe4866040518082815260200191505060405180910390a3505060016000555050565b600281565b6003546001600160a01b031681565b6000600260ff831610611dca576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b611dd2612efd565b60078360ff1660028110611de257fe5b6040805161014081018252600a92909202929092018054825260018101546020830152600281015492820192909252600382015460ff9081161515606083015260048301546080830152600583015460a083015260068301548116151560c08301819052600784015460e0840152600884015490911615156101008301526009909201546101208201529150611e89578051611e8190600019906129ec565b915050610bdf565b611ebd8160800151611eb76064611eb185600001518660e00151612a4990919063ffffffff16565b90612aa2565b906129ec565b9392505050565b6060808267ffffffffffffffff81118015611ede57600080fd5b50604051908082528060200260200182016040528015611f1857816020015b611f05612f59565b815260200190600190039081611efd5790505b50905060005b60ff8116841115611fcc57600080600080600789898760ff16818110611f4057fe5b9050602002013560ff1660ff1660028110611f5757fe5b600a0201541115611f8c57611f848989898760ff16818110611f7557fe5b9050602002013560ff16612475565b919450925090505b604051806060016040528084815260200183815260200182815250858560ff1681518110611fb657fe5b6020908102919091010152505050600101611f1e565b50949350505050565b611fdd612770565b6001600160a01b0316611fee6113e2565b6001600160a01b031614612037576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6001600160a01b03811661207c5760405162461bcd60e51b8152600401808060200182810382526026815260200180612f9f6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6120e0612770565b6001600160a01b03166120f16113e2565b6001600160a01b03161461213a576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6004544310612182576040805162461bcd60e51b815260206004820152600f60248201526e1251d3c81a185cc81cdd185c9d1959608a1b604482015290519081900360640190fd5b600260ff8216106121d0576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b831561222c57606483101561222c576040805162461bcd60e51b815260206004820152601960248201527f4d6178204f766572666c6f77206174206c656173742031303000000000000000604482015290519081900360640190fd5b8760078260ff166002811061223d57fe5b600a0201600101819055508660078260ff166002811061225957fe5b600a02015585600760ff83166002811061226f57fe5b600a0201600201819055508460078260ff166002811061228b57fe5b600a020160030160006101000a81548160ff0219169083151502179055508360078260ff16600281106122ba57fe5b600a020160060160006101000a81548160ff0219169083151502179055508260078260ff16600281106122e957fe5b600a0201600701819055508160078260ff166002811061230557fe5b600a0201600801805460ff191691151591909117905560408051898152602081018990528082018890528615156060820152851515608082015260a0810185905283151560c0820152905160ff8316917fac27037d7f6ad40b451eae58433743ec0b8e8a2f863f3bbef6ebbe90bdc2adff9160e0918190039190910190a25050505050505050565b60006123cd858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061285592505050565b95945050505050565b6060808267ffffffffffffffff811180156123f057600080fd5b5060405190808252806020026020018201604052801561241a578160200160208202803683370190505b50905060005b60ff8116841115611fcc5761244d8686868460ff1681811061243e57fe5b9050602002013560ff16612b09565b828260ff168151811061245c57fe5b6020908102919091010152600101612420565b3b151590565b60008060008060008060078760ff166002811061248e57fe5b600a020154600760ff8916600281106124a357fe5b600a02016004015411156125cd5760006124bd8989612b09565b90506124f264e8d4a51000611eb18360078c60ff16600281106124dc57fe5b600a020160010154612a4990919063ffffffff16565b9350600061251e64e8d4a51000611eb18460078d60ff166002811061251357fe5b600a02015490612a49565b6001600160a01b038b166000908152601b6020908152604080832060ff8e16845290915290205490915061255290826129ec565b935060078960ff166002811061256457fe5b600a02016003015460ff16156125c65760006125a160078b60ff166002811061258957fe5b600a02016004015460078c60ff1660028110610bd257fe5b90506125b664e8d4a51000611eb18784612a49565b93506125c285856129ec565b9450505b5050612636565b506000905080612633600760ff8916600281106125e657fe5b600a020154611eb1600760ff8b16600281106125fe57fe5b600a0201600101546001600160a01b038c166000908152601b6020908152604080832060ff8f16845290915290205490612a49565b92505b919450925090509250925092565b60008282018381101561269e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526126f9908490612b8c565b505050565b60008061270b8484612aa2565b905060c881106127225763773594009150506126a1565b6064811061273757639502f9009150506126a1565b6032811061274c5763b2d05e009150506126a1565b601981106127625764012a05f2009150506126a1565b6402540be4009150506126a1565b3390565b6000600260ff8316106127c4576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b60078260ff16600281106127d457fe5b600a02016006015460ff166127eb57506000610bdf565b600061283060078460ff166002811061280057fe5b600a020154611eb16064600760ff88166002811061281a57fe5b600a020160040154612a4990919063ffffffff16565b905060078360ff166002811061284257fe5b600a020160070154811015915050919050565b6000600260ff8416106128a5576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b60078360ff16600281106128b557fe5b600a02016008015460ff166128cc57506001611ebd565b60078360ff16600281106128dc57fe5b600a0201600901546000801b1415612932576040805162461bcd60e51b815260206004820152601460248201527315da1a5d195b1a5cdd081a5cc81b9bdd081cd95d60621b604482015290519081900360640190fd5b604080516bffffffffffffffffffffffff19606087901b1660208083019190915282518083036014018152603490920190925280519101206123cd83600760ff87166002811061297e57fe5b600a02016009015483612c3d565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526129e6908590612b8c565b50505050565b600082821115612a43576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082612a58575060006126a1565b82820282848281612a6557fe5b041461269e5760405162461bcd60e51b81526004018080602001828103825260218152602001806130496021913960400191505060405180910390fd5b6000808211612af8576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381612b0157fe5b049392505050565b60008060078360ff1660028110612b1c57fe5b600a0201600401541115612b8457612b7d612b44620f424060078560ff166002811061281a57fe5b6001600160a01b0385166000908152601b6020908152604080832060ff88168452909152902054611eb190670de0b6b3a7640000612a49565b90506126a1565b5060006126a1565b6060612be1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ce69092919063ffffffff16565b8051909150156126f957808060200190516020811015612c0057600080fd5b50516126f95760405162461bcd60e51b815260040180806020018281038252602a81526020018061308a602a913960400191505060405180910390fd5b600081815b8551811015612cdb576000868281518110612c5957fe5b60200260200101519050808311612ca05782816040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209250612cd2565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b50600101612c42565b509092149392505050565b6060612cf58484600085612cfd565b949350505050565b606082471015612d3e5760405162461bcd60e51b8152600401808060200182810382526026815260200180612ff36026913960400191505060405180910390fd5b612d478561246f565b612d98576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612dd75780518252601f199092019160209182019101612db8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612e39576040519150601f19603f3d011682016040523d82523d6000602084013e612e3e565b606091505b5091509150612e4e828286612e59565b979650505050505050565b60608315612e68575081611ebd565b825115612e785782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612ec2578181015183820152602001612eaa565b50505050905090810190601f168015612eef5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b604051806101400160405280600081526020016000815260200160008152602001600015158152602001600081526020016000815260200160001515815260200160008152602001600015158152602001600080191681525090565b6040518060600160405280600390602082028036833750919291505056fe4465706f73697420616d6f756e742061626f766520746865206f766572666c6f77206c696d69744f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734e6577207374617274426c6f636b206d757374206265206c6f776572207468616e206e657720656e64426c6f636b416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4e6577207374617274426c6f636b206d75737420626520686967686572207468616e2063757272656e7420626c6f636b536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122046a2cbab5d7df1d2dafb9f625a21deeb768bf1703065d24a4136cce7e7cd076664736f6c634300060c00334f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573738be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0000000000000000000000000bf62c67ea509e86f07c8c69d0286c0636c50270b0000000000000000000000000804702a4e749d39a35fde73d1df0b1f1d6b83470000000000000000000000000000000000000000000000000000000000107b75000000000000000000000000000000000000000000000000000000000010b5ed00000000000000000000000048e1ae0c9c2394a8cf91cd2fff713028ca71f087
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c80638da5cb5b116100de578063b781360711610097578063f2fde38b11610071578063f2fde38b14610638578063f9a1dedb1461065e578063f9a6a1fd146106af578063f9cd5c121461073557610173565b8063b781360714610521578063c6b8358c14610529578063ca463ca41461054957610173565b80638da5cb5b146104305780638ed5b0fc146104385780639513997f146104405780639f1b524814610463578063add075e114610486578063b42392f11461050357610173565b806348cd4cb11161013057806348cd4cb1146102a25780634af3c9b7146102aa5780635fcbd285146103c1578063715018a6146103e557806377aef522146103ed578063795f46ac1461041357610173565b8063083c6323146101785780632374876c1461019257806337f859b8146101b45780633f138d4b146101d15780633f6500bf146101fd57806346ab91bf14610231575b600080fd5b610180610803565b60408051918252519081900360200190f35b6101b2600480360360208110156101a857600080fd5b503560ff16610809565b005b610180600480360360208110156101ca57600080fd5b5035610b87565b6101b2600480360360408110156101e757600080fd5b506001600160a01b038135169060200135610be4565b61021d6004803603602081101561021357600080fd5b503560ff16610e23565b604080519115158252519081900360200190f35b61024e6004803603602081101561024757600080fd5b5035610e2e565b604080519a8b5260208b0199909952898901979097529415156060890152608088019390935260a0870191909152151560c086015260e0850152151561010084015261012083015251908190036101400190f35b610180610f51565b610328600480360360408110156102c057600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156102ea57600080fd5b8201836020820111156102fc57600080fd5b803590602001918460208302840111600160201b8311171561031d57600080fd5b509092509050610f57565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561036c578181015183820152602001610354565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156103ab578181015183820152602001610393565b5050505090500194505050505060405180910390f35b6103c96110f1565b604080516001600160a01b039092168252519081900360200190f35b6101b2611100565b6101b26004803603604081101561040357600080fd5b5060ff81351690602001356111ac565b6101b26004803603602081101561042957600080fd5b50356112ff565b6103c96113e2565b6101806113f1565b6101b26004803603604081101561045657600080fd5b50803590602001356113f7565b6101b26004803603604081101561047957600080fd5b5080359060200135611566565b6101b26004803603606081101561049c57600080fd5b81359160ff60208201351691810190606081016040820135600160201b8111156104c557600080fd5b8201836020820111156104d757600080fd5b803590602001918460208302840111600160201b831117156104f857600080fd5b5090925090506117ce565b61050b611d66565b6040805160ff9092168252519081900360200190f35b6103c9611d6b565b6101806004803603602081101561053f57600080fd5b503560ff16611d7a565b6105c76004803603604081101561055f57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561058957600080fd5b82018360208201111561059b57600080fd5b803590602001918460208302840111600160201b831117156105bc57600080fd5b509092509050611ec4565b60405180806020018281038252838181518152602001915080516000925b8184101561062757602080850284010151606080838360005b838110156106165781810151838201526020016105fe565b5050505090500192600101926105e5565b925050509250505060405180910390f35b6101b26004803603602081101561064e57600080fd5b50356001600160a01b0316611fd5565b6101b2600480360361010081101561067557600080fd5b508035906020810135906040810135906060810135151590608081013515159060a08101359060c081013515159060e0013560ff166120d8565b61021d600480360360608110156106c557600080fd5b6001600160a01b038235169160ff60208201351691810190606081016040820135600160201b8111156106f757600080fd5b82018360208201111561070957600080fd5b803590602001918460208302840111600160201b8311171561072a57600080fd5b50909250905061238d565b6107b36004803603604081101561074b57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561077557600080fd5b82018360208201111561078757600080fd5b803590602001918460208302840111600160201b831117156107a857600080fd5b5090925090506123d6565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107ef5781810151838201526020016107d7565b505050509050019250505060405180910390f35b60055481565b60026000541415610861576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005561086f3361246f565b156108b8576040805162461bcd60e51b815260206004820152601460248201527318dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604482015290519081900360640190fd5b33321461090c576040805162461bcd60e51b815260206004820152601a60248201527f70726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000604482015290519081900360640190fd5b6005544311610959576040805162461bcd60e51b8152602060048201526014602482015273151bdbc819585c9b1e481d1bc81a185c9d995cdd60621b604482015290519081900360640190fd5b600260ff8216106109a7576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b336000908152601b6020908152604080832060ff85168452909152902054610a0c576040805162461bcd60e51b8152602060048201526013602482015272446964206e6f7420706172746963697061746560681b604482015290519081900360640190fd5b336000908152601b6020908152604080832060ff80861685529252909120600101541615610a71576040805162461bcd60e51b815260206004820152600d60248201526c12185cc81a185c9d995cdd1959609a1b604482015290519081900360640190fd5b336000818152601b6020908152604080832060ff8616845290915281206001908101805460ff191690911790559081908190610aad9085612475565b919450925090508015610b0057610ae48160078660ff1660028110610ace57fe5b600a02016005015461264490919063ffffffff16565b60078560ff1660028110610af457fe5b600a0201600501819055505b8215610b1d57600354610b1d906001600160a01b031633856126a7565b8115610b3a57600254610b3a906001600160a01b031633846126a7565b6040805184815260208101849052815160ff87169233927f1839f39a4e3eeee0272f5304923e2c487330fadc80f6df38384c8fdaf396580a929081900390910190a3505060016000555050565b600060078260028110610b9657fe5b600a02016003015460ff16610bad57506000610bdf565b610bdc60078360028110610bbd57fe5b600a02016004015460078460028110610bd257fe5b600a0201546126fe565b90505b919050565b610bec612770565b6001600160a01b0316610bfd6113e2565b6001600160a01b031614610c46576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6002546001600160a01b0383811691161415610c9e576040805162461bcd60e51b815260206004820152601260248201527121b0b73737ba103132902628103a37b5b2b760711b604482015290519081900360640190fd5b6003546001600160a01b0383811691161415610d01576040805162461bcd60e51b815260206004820152601860248201527f43616e6e6f74206265206f66666572696e6720746f6b656e0000000000000000604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610d4757600080fd5b505afa158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b5051811115610dc7576040805162461bcd60e51b815260206004820181905260248201527f43616e6e6f74207265636f766572206d6f7265207468616e2062616c616e6365604482015290519081900360640190fd5b610ddb6001600160a01b03831633836126a7565b604080516001600160a01b03841681526020810183905281517f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab78129929181900390910190a15050565b6000610bdc82612774565b600080600080600080600080600080610e45612efd565b60078c60028110610e5257fe5b600a0201604051806101400160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815260200160048201548152602001600582015481526020016006820160009054906101000a900460ff16151515158152602001600782015481526020016008820160009054906101000a900460ff161515151581526020016009820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e001518861010001518961012001519a509a509a509a509a509a509a509a509a509a50509193959799509193959799565b60045481565b606080808367ffffffffffffffff81118015610f7257600080fd5b50604051908082528060200260200182016040528015610f9c578160200160208202803683370190505b50905060608467ffffffffffffffff81118015610fb857600080fd5b50604051908082528060200260200182016040528015610fe2578160200160208202803683370190505b50905060005b60ff81168611156110e4576001600160a01b0388166000908152601b6020526040812090888860ff851681811061101b57fe5b9050602002013560ff1660ff1660ff16815260200190815260200160002060000154838260ff168151811061104c57fe5b602002602001018181525050601b6000896001600160a01b03166001600160a01b03168152602001908152602001600020600088888460ff1681811061108e57fe5b9050602002013560ff1660ff1660ff16815260200190815260200160002060010160009054906101000a900460ff16828260ff16815181106110cc57fe5b91151560209283029190910190910152600101610fe8565b5090969095509350505050565b6002546001600160a01b031681565b611108612770565b6001600160a01b03166111196113e2565b6001600160a01b031614611162576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6111b4612770565b6001600160a01b03166111c56113e2565b6001600160a01b03161461120e576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6004544310611256576040805162461bcd60e51b815260206004820152600f60248201526e1251d3c81a185cc81cdd185c9d1959608a1b604482015290519081900360640190fd5b600260ff8316106112a4576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b8060078360ff16600281106112b557fe5b600a0201600901819055508160ff167ffd91ec8ce9c48e69d6b6d618cc3102804bac2d28fd3b8ac26fc1fa887194e311826040518082815260200191505060405180910390a25050565b611307612770565b6001600160a01b03166113186113e2565b6001600160a01b031614611361576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b60055443106113a7576040805162461bcd60e51b815260206004820152600d60248201526c1251d3c81a185cc8195b991959609a1b604482015290519081900360640190fd5b60068190556040805182815290517fb3858839cb95bac816de879b29203046e91b49859f71499c319ce06688891cb99181900360200190a150565b6001546001600160a01b031690565b60065481565b6113ff612770565b6001600160a01b03166114106113e2565b6001600160a01b031614611459576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b60045443106114a1576040805162461bcd60e51b815260206004820152600f60248201526e1251d3c81a185cc81cdd185c9d1959608a1b604482015290519081900360640190fd5b8082106114df5760405162461bcd60e51b815260040180806020018281038252602e815260200180612fc5602e913960400191505060405180910390fd5b81431061151d5760405162461bcd60e51b81526004018080602001828103825260308152602001806130196030913960400191505060405180910390fd5b60048290556005819055604080518381526020810183905281517f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce06929181900390910190a15050565b61156e612770565b6001600160a01b031661157f6113e2565b6001600160a01b0316146115c8576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b600254604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561161357600080fd5b505afa158015611627573d6000803e3d6000fd5b505050506040513d602081101561163d57600080fd5b505182111561168a576040805162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768204c5020746f6b656e7360601b604482015290519081900360640190fd5b600354604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156116d557600080fd5b505afa1580156116e9573d6000803e3d6000fd5b505050506040513d60208110156116ff57600080fd5b5051811115611755576040805162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f756768206f66666572696e6720746f6b656e00000000000000604482015290519081900360640190fd5b811561177257600254611772906001600160a01b031633846126a7565b801561178f5760035461178f906001600160a01b031633836126a7565b604080518381526020810183905281517f94ebb62a252249c867ecb758d386f50a95be7e8df9e1c52917c9cf494327dd7d929181900390910190a15050565b60026000541415611826576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556118343361246f565b1561187d576040805162461bcd60e51b815260206004820152601460248201527318dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604482015290519081900360640190fd5b3332146118d1576040805162461bcd60e51b815260206004820152601a60248201527f70726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000604482015290519081900360640190fd5b600260ff84161061191f576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b600060078460ff166002811061193157fe5b600a02016001015411801561195a5750600060078460ff166002811061195357fe5b600a020154115b61199a576040805162461bcd60e51b815260206004820152600c60248201526b141bdbdb081b9bdd081cd95d60a21b604482015290519081900360640190fd5b60078360ff16600281106119aa57fe5b600a02016008015460ff1615611a49576119f8338484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061285592505050565b611a49576040805162461bcd60e51b815260206004820152601760248201527f55736572206973206e6f742077686974656c6973746564000000000000000000604482015290519081900360640190fd5b60078360ff1660028110611a5957fe5b600a02016006015460ff1615611afe57611a7283612774565b15611ab7576040805162461bcd60e51b815260206004820152601060248201526f141bdbdb0818d85c081c995858da195960821b604482015290519081900360640190fd5b83611ac184611d7a565b1015611afe5760405162461bcd60e51b8152600401808060200182810382526027815260200180612f786027913960400191505060405180910390fd5b6004544311611b40576040805162461bcd60e51b8152602060048201526009602482015268546f6f206561726c7960b81b604482015290519081900360640190fd5b6005544310611b81576040805162461bcd60e51b8152602060048201526008602482015267546f6f206c61746560c01b604482015290519081900360640190fd5b60008411611bcb576040805162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b604482015290519081900360640190fd5b600254611be3906001600160a01b031633308761298c565b336000908152601b6020908152604080832060ff87168452909152902054611c0b9085612644565b336000908152601b6020908152604080832060ff881680855292528220929092559060079060028110611c3a57fe5b600a0201600201541115611cd15760078360ff1660028110611c5857fe5b600a020160020154336000908152601b6020908152604080832060ff881684529091529020541115611cd1576040805162461bcd60e51b815260206004820152601b60248201527f4e657720616d6f756e742061626f76652075736572206c696d69740000000000604482015290519081900360640190fd5b611cfb8460078560ff1660028110611ce557fe5b600a02016004015461264490919063ffffffff16565b60078460ff1660028110611d0b57fe5b600a0201600401819055508260ff16336001600160a01b03167fe6ea2883ec66613be5cdd4954e8c4919bdb7982e6e2d907011bc051bfcde7fe4866040518082815260200191505060405180910390a3505060016000555050565b600281565b6003546001600160a01b031681565b6000600260ff831610611dca576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b611dd2612efd565b60078360ff1660028110611de257fe5b6040805161014081018252600a92909202929092018054825260018101546020830152600281015492820192909252600382015460ff9081161515606083015260048301546080830152600583015460a083015260068301548116151560c08301819052600784015460e0840152600884015490911615156101008301526009909201546101208201529150611e89578051611e8190600019906129ec565b915050610bdf565b611ebd8160800151611eb76064611eb185600001518660e00151612a4990919063ffffffff16565b90612aa2565b906129ec565b9392505050565b6060808267ffffffffffffffff81118015611ede57600080fd5b50604051908082528060200260200182016040528015611f1857816020015b611f05612f59565b815260200190600190039081611efd5790505b50905060005b60ff8116841115611fcc57600080600080600789898760ff16818110611f4057fe5b9050602002013560ff1660ff1660028110611f5757fe5b600a0201541115611f8c57611f848989898760ff16818110611f7557fe5b9050602002013560ff16612475565b919450925090505b604051806060016040528084815260200183815260200182815250858560ff1681518110611fb657fe5b6020908102919091010152505050600101611f1e565b50949350505050565b611fdd612770565b6001600160a01b0316611fee6113e2565b6001600160a01b031614612037576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6001600160a01b03811661207c5760405162461bcd60e51b8152600401808060200182810382526026815260200180612f9f6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6120e0612770565b6001600160a01b03166120f16113e2565b6001600160a01b03161461213a576040805162461bcd60e51b8152602060048201819052602482015260008051602061306a833981519152604482015290519081900360640190fd5b6004544310612182576040805162461bcd60e51b815260206004820152600f60248201526e1251d3c81a185cc81cdd185c9d1959608a1b604482015290519081900360640190fd5b600260ff8216106121d0576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b831561222c57606483101561222c576040805162461bcd60e51b815260206004820152601960248201527f4d6178204f766572666c6f77206174206c656173742031303000000000000000604482015290519081900360640190fd5b8760078260ff166002811061223d57fe5b600a0201600101819055508660078260ff166002811061225957fe5b600a02015585600760ff83166002811061226f57fe5b600a0201600201819055508460078260ff166002811061228b57fe5b600a020160030160006101000a81548160ff0219169083151502179055508360078260ff16600281106122ba57fe5b600a020160060160006101000a81548160ff0219169083151502179055508260078260ff16600281106122e957fe5b600a0201600701819055508160078260ff166002811061230557fe5b600a0201600801805460ff191691151591909117905560408051898152602081018990528082018890528615156060820152851515608082015260a0810185905283151560c0820152905160ff8316917fac27037d7f6ad40b451eae58433743ec0b8e8a2f863f3bbef6ebbe90bdc2adff9160e0918190039190910190a25050505050505050565b60006123cd858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061285592505050565b95945050505050565b6060808267ffffffffffffffff811180156123f057600080fd5b5060405190808252806020026020018201604052801561241a578160200160208202803683370190505b50905060005b60ff8116841115611fcc5761244d8686868460ff1681811061243e57fe5b9050602002013560ff16612b09565b828260ff168151811061245c57fe5b6020908102919091010152600101612420565b3b151590565b60008060008060008060078760ff166002811061248e57fe5b600a020154600760ff8916600281106124a357fe5b600a02016004015411156125cd5760006124bd8989612b09565b90506124f264e8d4a51000611eb18360078c60ff16600281106124dc57fe5b600a020160010154612a4990919063ffffffff16565b9350600061251e64e8d4a51000611eb18460078d60ff166002811061251357fe5b600a02015490612a49565b6001600160a01b038b166000908152601b6020908152604080832060ff8e16845290915290205490915061255290826129ec565b935060078960ff166002811061256457fe5b600a02016003015460ff16156125c65760006125a160078b60ff166002811061258957fe5b600a02016004015460078c60ff1660028110610bd257fe5b90506125b664e8d4a51000611eb18784612a49565b93506125c285856129ec565b9450505b5050612636565b506000905080612633600760ff8916600281106125e657fe5b600a020154611eb1600760ff8b16600281106125fe57fe5b600a0201600101546001600160a01b038c166000908152601b6020908152604080832060ff8f16845290915290205490612a49565b92505b919450925090509250925092565b60008282018381101561269e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526126f9908490612b8c565b505050565b60008061270b8484612aa2565b905060c881106127225763773594009150506126a1565b6064811061273757639502f9009150506126a1565b6032811061274c5763b2d05e009150506126a1565b601981106127625764012a05f2009150506126a1565b6402540be4009150506126a1565b3390565b6000600260ff8316106127c4576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b60078260ff16600281106127d457fe5b600a02016006015460ff166127eb57506000610bdf565b600061283060078460ff166002811061280057fe5b600a020154611eb16064600760ff88166002811061281a57fe5b600a020160040154612a4990919063ffffffff16565b905060078360ff166002811061284257fe5b600a020160070154811015915050919050565b6000600260ff8416106128a5576040805162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b60078360ff16600281106128b557fe5b600a02016008015460ff166128cc57506001611ebd565b60078360ff16600281106128dc57fe5b600a0201600901546000801b1415612932576040805162461bcd60e51b815260206004820152601460248201527315da1a5d195b1a5cdd081a5cc81b9bdd081cd95d60621b604482015290519081900360640190fd5b604080516bffffffffffffffffffffffff19606087901b1660208083019190915282518083036014018152603490920190925280519101206123cd83600760ff87166002811061297e57fe5b600a02016009015483612c3d565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526129e6908590612b8c565b50505050565b600082821115612a43576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082612a58575060006126a1565b82820282848281612a6557fe5b041461269e5760405162461bcd60e51b81526004018080602001828103825260218152602001806130496021913960400191505060405180910390fd5b6000808211612af8576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381612b0157fe5b049392505050565b60008060078360ff1660028110612b1c57fe5b600a0201600401541115612b8457612b7d612b44620f424060078560ff166002811061281a57fe5b6001600160a01b0385166000908152601b6020908152604080832060ff88168452909152902054611eb190670de0b6b3a7640000612a49565b90506126a1565b5060006126a1565b6060612be1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ce69092919063ffffffff16565b8051909150156126f957808060200190516020811015612c0057600080fd5b50516126f95760405162461bcd60e51b815260040180806020018281038252602a81526020018061308a602a913960400191505060405180910390fd5b600081815b8551811015612cdb576000868281518110612c5957fe5b60200260200101519050808311612ca05782816040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209250612cd2565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b50600101612c42565b509092149392505050565b6060612cf58484600085612cfd565b949350505050565b606082471015612d3e5760405162461bcd60e51b8152600401808060200182810382526026815260200180612ff36026913960400191505060405180910390fd5b612d478561246f565b612d98576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612dd75780518252601f199092019160209182019101612db8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612e39576040519150601f19603f3d011682016040523d82523d6000602084013e612e3e565b606091505b5091509150612e4e828286612e59565b979650505050505050565b60608315612e68575081611ebd565b825115612e785782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612ec2578181015183820152602001612eaa565b50505050905090810190601f168015612eef5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b604051806101400160405280600081526020016000815260200160008152602001600015158152602001600081526020016000815260200160001515815260200160008152602001600015158152602001600080191681525090565b6040518060600160405280600390602082028036833750919291505056fe4465706f73697420616d6f756e742061626f766520746865206f766572666c6f77206c696d69744f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734e6577207374617274426c6f636b206d757374206265206c6f776572207468616e206e657720656e64426c6f636b416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4e6577207374617274426c6f636b206d75737420626520686967686572207468616e2063757272656e7420626c6f636b536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122046a2cbab5d7df1d2dafb9f625a21deeb768bf1703065d24a4136cce7e7cd076664736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000bf62c67ea509e86f07c8c69d0286c0636c50270b0000000000000000000000000804702a4e749d39a35fde73d1df0b1f1d6b83470000000000000000000000000000000000000000000000000000000000107b75000000000000000000000000000000000000000000000000000000000010b5ed00000000000000000000000048e1ae0c9c2394a8cf91cd2fff713028ca71f087
-----Decoded View---------------
Arg [0] : _lpToken (address): 0xbf62c67eA509E86F07c8c69d0286C0636C50270b
Arg [1] : _offeringToken (address): 0x0804702a4E749d39A35FDe73d1DF0B1f1D6b8347
Arg [2] : _startBlock (uint256): 1080181
Arg [3] : _endBlock (uint256): 1095149
Arg [4] : _adminAddress (address): 0x48E1Ae0C9c2394a8cf91cD2fff713028Ca71f087
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000bf62c67ea509e86f07c8c69d0286c0636c50270b
Arg [1] : 0000000000000000000000000804702a4e749d39a35fde73d1df0b1f1d6b8347
Arg [2] : 0000000000000000000000000000000000000000000000000000000000107b75
Arg [3] : 000000000000000000000000000000000000000000000000000000000010b5ed
Arg [4] : 00000000000000000000000048e1ae0c9c2394a8cf91cd2fff713028ca71f087
Deployed Bytecode Sourcemap
46073:25746:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46498:23;;;:::i;:::-;;;;;;;;;;;;;;;;52980:1692;;;;;;;;;;;;;;;;-1:-1:-1;52980:1692:0;;;;:::i;:::-;;61773:337;;;;;;;;;;;;;;;;-1:-1:-1;61773:337:0;;:::i;56302:527::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56302:527:0;;;;;;;;:::i;65874:167::-;;;;;;;;;;;;;;;;-1:-1:-1;65874:167:0;;;;:::i;:::-;;;;;;;;;;;;;;;;;;60651:832;;;;;;;;;;;;;;;;-1:-1:-1;60651:832:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46425:25;;;:::i;63412:555::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63412:555:0;;;;;;;;;;;;;;;-1:-1:-1;;;63412:555:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;63412:555:0;;;;;;;;;;-1:-1:-1;63412:555:0;;-1:-1:-1;63412:555:0;-1:-1:-1;63412:555:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46221:21;;;:::i;:::-;;;;-1:-1:-1;;;;;46221:21:0;;;;;;;;;;;;;;28806:148;;;:::i;54815:317::-;;;;;;;;;;;;;;;;-1:-1:-1;54815:317:0;;;;;;;;;:::i;58725:237::-;;;;;;;;;;;;;;;;-1:-1:-1;58725:237:0;;:::i;28155:87::-;;;:::i;46565:25::-;;;:::i;59201:485::-;;;;;;;;;;;;;;;;-1:-1:-1;59201:485:0;;;;;;;:::i;55412:580::-;;;;;;;;;;;;;;;;-1:-1:-1;55412:580:0;;;;;;;:::i;50700:2172::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;50700:2172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;50700:2172:0;;;;;;;;;;-1:-1:-1;50700:2172:0;;-1:-1:-1;50700:2172:0;-1:-1:-1;50700:2172:0;:::i;46338:37::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;46278:27;;;:::i;65222:491::-;;;;;;;;;;;;;;;;-1:-1:-1;65222:491:0;;;;:::i;64161:912::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64161:912:0;;;;;;;;;;;;;;;-1:-1:-1;;;64161:912:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;64161:912:0;;;;;;;;;;-1:-1:-1;64161:912:0;;-1:-1:-1;64161:912:0;-1:-1:-1;64161:912:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29109:244;;;;;;;;;;;;;;;;-1:-1:-1;29109:244:0;-1:-1:-1;;;;;29109:244:0;;:::i;57383:1156::-;;;;;;;;;;;;;;;;-1:-1:-1;57383:1156:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;63039:211::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63039:211:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;63039:211:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;63039:211:0;;;;;;;;;;-1:-1:-1;63039:211:0;;-1:-1:-1;63039:211:0;-1:-1:-1;63039:211:0;:::i;62303:415::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62303:415:0;;;;;;;;;;;;;;;-1:-1:-1;;;62303:415:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;62303:415:0;;;;;;;;;;-1:-1:-1;62303:415:0;;-1:-1:-1;62303:415:0;-1:-1:-1;62303:415:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46498:23;;;;:::o;52980:1692::-;1723:1;2329:7;;:19;;2321:63;;;;;-1:-1:-1;;;2321:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1723:1;2462:7;:18;49304:23:::1;49316:10;49304:11;:23::i;:::-;49303:24;49295:57;;;::::0;;-1:-1:-1;;;49295:57:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;49295:57:0;;;;;;;;;;;;;::::1;;49371:10;49385:9;49371:23;49363:62;;;::::0;;-1:-1:-1;;;49363:62:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;53144:8:::2;;53129:12;:23;53121:56;;;::::0;;-1:-1:-1;;;53121:56:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;53121:56:0;;;;;;;;;;;;;::::2;;46374:1;53242:18;::::0;::::2;;53234:50;;;::::0;;-1:-1:-1;;;53234:50:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;53234:50:0;;;;;;;;;;;;;::::2;;53368:10;53399:1;53358:21:::0;;;:9:::2;:21;::::0;;;;;;;:27:::2;::::0;::::2;::::0;;;;;;;:38;53350:74:::2;;;::::0;;-1:-1:-1;;;53350:74:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;53350:74:0;;;;;;;;;;;;;::::2;;53514:10;53504:21;::::0;;;:9:::2;:21;::::0;;;;;;;:27:::2;::::0;;::::2;::::0;;;;;;;:39:::2;;::::0;::::2;53503:40;53495:66;;;::::0;;-1:-1:-1;;;53495:66:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;53495:66:0;;;;;;;;;;;;;::::2;;53623:10;53613:21;::::0;;;:9:::2;:21;::::0;;;;;;;:27:::2;::::0;::::2;::::0;;;;;;;53655:4:::2;53613:39:::0;;::::2;:46:::0;;-1:-1:-1;;53613:46:0::2;::::0;;::::2;::::0;;:21;;;;;53938:96:::2;::::0;53635:4;53938:41:::2;:96::i;:::-;53875:159:::0;;-1:-1:-1;53875:159:0;-1:-1:-1;53875:159:0;-1:-1:-1;54094:19:0;;54090:154:::2;;54172:60;54216:15;54172:16;54189:4;54172:22;;;;;;;;;;;;:39;;;:43;;:60;;;;:::i;:::-;54130:16;54147:4;54130:22;;;;;;;;;;;;:39;;:102;;;;54090:154;54327:23:::0;;54323:124:::2;;54367:13;::::0;:68:::2;::::0;-1:-1:-1;;;;;54367:13:0::2;54402:10;54415:19:::0;54367:26:::2;:68::i;:::-;54463:24:::0;;54459:120:::2;;54504:7;::::0;:63:::2;::::0;-1:-1:-1;;;;;54504:7:0::2;54533:10;54546:20:::0;54504::::2;:63::i;:::-;54596:68;::::0;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;::::2;::::0;54604:10:::2;::::0;54596:68:::2;::::0;;;;;;;;;::::2;-1:-1:-1::0;;1679:1:0;2641:7;:22;-1:-1:-1;;52980:1692:0:o;61773:337::-;61852:7;61877:16;61894:4;61877:22;;;;;;;;;;:29;;;;;61872:231;;-1:-1:-1;61930:1:0;61923:8;;61872:231;61988:103;62010:16;62027:4;62010:22;;;;;;;;;;:38;;;62050:16;62067:4;62050:22;;;;;;;;;;:40;61988:21;:103::i;:::-;61964:127;;61872:231;61773:337;;;:::o;56302:527::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;56438:7:::1;::::0;-1:-1:-1;;;;;56413:33:0;;::::1;56438:7:::0;::::1;56413:33;;56405:64;;;::::0;;-1:-1:-1;;;56405:64:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;56405:64:0;;;;;;;;;;;;;::::1;;56513:13;::::0;-1:-1:-1;;;;;56488:39:0;;::::1;56513:13:::0;::::1;56488:39;;56480:76;;;::::0;;-1:-1:-1;;;56480:76:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;56591:46;::::0;;-1:-1:-1;;;56591:46:0;;56631:4:::1;56591:46;::::0;::::1;::::0;;;-1:-1:-1;;;;;56591:31:0;::::1;::::0;::::1;::::0;:46;;;;;::::1;::::0;;;;;;;;:31;:46;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;56591:46:0;56575:62;::::1;;56567:107;;;::::0;;-1:-1:-1;;;56567:107:0;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;56687:69;-1:-1:-1::0;;;;;56687:34:0;::::1;56730:10;56743:12:::0;56687:34:::1;:69::i;:::-;56774:47;::::0;;-1:-1:-1;;;;;56774:47:0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;;::::1;56302:527:::0;;:::o;65874:167::-;65984:4;66006:27;66028:4;66006:21;:27::i;60651:832::-;60776:7;60798;60820;60842:4;60861:7;60883;60905:4;60924:7;60946:4;60965:7;61000:36;;:::i;:::-;61039:16;61056:4;61039:22;;;;;;;;;;61000:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61094:9;:27;;;61136:9;:28;;;61179:9;:26;;;61220:9;:16;;;61251:9;:25;;;61291:9;:26;;;61332:9;:24;;;61371:9;:21;;;61407:9;:22;;;61444:9;:20;;;61072:403;;;;;;;;;;;;;;;;;;;;;60651:832;;;;;;;;;;;:::o;46425:25::-;;;;:::o;63412:555::-;63541:16;;;63635:5;63621:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63621:27:0;-1:-1:-1;63590:58:0;-1:-1:-1;63659:25:0;63698:5;63687:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63687:24:0;;63659:52;;63729:7;63724:192;63742:16;;;;-1:-1:-1;63724:192:0;;;-1:-1:-1;;;;;63797:16:0;;;;;;:9;:16;;;;;;63814:5;;:8;;;;;;;;;;;;;;;;;;63797:26;;;;;;;;;;;;;;;:37;;;63780:11;63792:1;63780:14;;;;;;;;;;;;;;;:54;;;;;63866:9;:16;63876:5;-1:-1:-1;;;;;63866:16:0;-1:-1:-1;;;;;63866:16:0;;;;;;;;;;;;:26;63883:5;;63889:1;63883:8;;;;;;;;;;;;;;;;;63866:26;;;;;;;;;;;;;;;:38;;;;;;;;;;;;63849:11;63861:1;63849:14;;;;;;;;;;:55;;;:14;;;;;;;;;;;:55;63760:3;;63724:192;;;-1:-1:-1;63934:11:0;;;;-1:-1:-1;63412:555:0;-1:-1:-1;;;;63412:555:0:o;46221:21::-;;;-1:-1:-1;;;;;46221:21:0;;:::o;28806:148::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;28897:6:::1;::::0;28876:40:::1;::::0;28913:1:::1;::::0;-1:-1:-1;;;;;28897:6:0::1;::::0;28876:40:::1;::::0;28913:1;;28876:40:::1;28927:6;:19:::0;;-1:-1:-1;;;;;;28927:19:0::1;::::0;;28806:148::o;54815:317::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;54930:10:::1;;54915:12;:25;54907:53;;;::::0;;-1:-1:-1;;;54907:53:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;54907:53:0;;;;;;;;;;;;;::::1;;46374:1;54977:18;::::0;::::1;;54969:50;;;::::0;;-1:-1:-1;;;54969:50:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;54969:50:0;;;;;;;;;;;;;::::1;;55066:11;55030:16;55047:4;55030:22;;;;;;;;;;;;:33;;:47;;;;55106:4;55093:31;;;55112:11;55093:31;;;;;;;;;;;;;;;;;;54815:317:::0;;:::o;58725:237::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;58850:8:::1;;58835:12;:23;58827:49;;;::::0;;-1:-1:-1;;;58827:49:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;58827:49:0;;;;;;;;;;;;;::::1;;58887:10;:24:::0;;;58929:25:::1;::::0;;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;58725:237:::0;:::o;28155:87::-;28228:6;;-1:-1:-1;;;;;28228:6:0;28155:87;:::o;46565:25::-;;;;:::o;59201:485::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;59327:10:::1;;59312:12;:25;59304:53;;;::::0;;-1:-1:-1;;;59304:53:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;59304:53:0;;;;;;;;;;;;;::::1;;59390:9;59376:11;:23;59368:82;;;;-1:-1:-1::0;;;59368:82:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59484:11;59469:12;:26;59461:87;;;;-1:-1:-1::0;;;59461:87:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59561:10;:24:::0;;;59596:8:::1;:20:::0;;;59634:44:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;;::::1;59201:485:::0;;:::o;55412:580::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;55536:7:::1;::::0;:32:::1;::::0;;-1:-1:-1;;;55536:32:0;;55562:4:::1;55536:32;::::0;::::1;::::0;;;-1:-1:-1;;;;;55536:7:0;;::::1;::::0;:17:::1;::::0;:32;;;;;::::1;::::0;;;;;;;;;:7;:32;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;55536:32:0;55523:45;::::1;;55515:78;;;::::0;;-1:-1:-1;;;55515:78:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;55515:78:0;;;;;;;;;;;;;::::1;;55628:13;::::0;:38:::1;::::0;;-1:-1:-1;;;55628:38:0;;55660:4:::1;55628:38;::::0;::::1;::::0;;;-1:-1:-1;;;;;55628:13:0;;::::1;::::0;:23:::1;::::0;:38;;;;;::::1;::::0;;;;;;;;;:13;:38;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;55628:38:0;55612:54;::::1;;55604:92;;;::::0;;-1:-1:-1;;;55604:92:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;55713:13:::0;;55709:98:::1;;55743:7;::::0;:52:::1;::::0;-1:-1:-1;;;;;55743:7:0::1;55772:10;55785:9:::0;55743:20:::1;:52::i;:::-;55823:16:::0;;55819:110:::1;;55856:13;::::0;:61:::1;::::0;-1:-1:-1;;;;;55856:13:0::1;55891:10;55904:12:::0;55856:26:::1;:61::i;:::-;55946:38;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;;::::1;55412:580:::0;;:::o;50700:2172::-;1723:1;2329:7;;:19;;2321:63;;;;;-1:-1:-1;;;2321:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1723:1;2462:7;:18;49304:23:::1;49316:10;49304:11;:23::i;:::-;49303:24;49295:57;;;::::0;;-1:-1:-1;;;49295:57:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;49295:57:0;;;;;;;;;;;;;::::1;;49371:10;49385:9;49371:23;49363:62;;;::::0;;-1:-1:-1;;;49363:62:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46374:1:::2;50887:18;::::0;::::2;;50879:50;;;::::0;;-1:-1:-1;;;50879:50:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;50879:50:0;;;;;;;;;;;;;::::2;;51045:1;51001:16;51018:4;51001:22;;;;;;;;;;;;:41;;;:45;:93;;;;;51093:1;51050:16;51067:4;51050:22;;;;;;;;;;;;:40:::0;:44:::2;51001:93;50979:155;;;::::0;;-1:-1:-1;;;50979:155:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;50979:155:0;;;;;;;;;;;;;::::2;;51207:16;51224:4;51207:22;;;;;;;;;;;;:35;;::::0;::::2;;51203:142;;;51265:40;51280:10;51292:4;51298:6;;51265:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;51265:14:0::2;::::0;-1:-1:-1;;;51265:40:0:i:2;:::-;51257:76;;;::::0;;-1:-1:-1;;;51257:76:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;51433:16;51450:4;51433:22;;;;;;;;;;;;:37;;::::0;::::2;;51429:241;;;51493:27;51515:4;51493:21;:27::i;:::-;:36;51485:65;;;::::0;;-1:-1:-1;;;51485:65:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;51485:65:0;;;;;;;;;;;;;::::2;;51607:7;51571:32;51598:4;51571:26;:32::i;:::-;:43;;51563:95;;;;-1:-1:-1::0;;;51563:95:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51766:10;;51751:12;:25;51743:47;;;::::0;;-1:-1:-1;;;51743:47:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;51743:47:0;;;;;;;;;;;;;::::2;;51886:8;;51871:12;:23;51863:44;;;::::0;;-1:-1:-1;;;51863:44:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;51863:44:0;;;;;;;;;;;;;::::2;;52004:1;51994:7;:11;51986:42;;;::::0;;-1:-1:-1;;;51986:42:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;51986:42:0;;;;;;;;;;;;;::::2;;52086:7;::::0;:69:::2;::::0;-1:-1:-1;;;;;52086:7:0::2;52119:10;52140:4;52147:7:::0;52086:24:::2;:69::i;:::-;52254:10;52244:21;::::0;;;:9:::2;:21;::::0;;;;;;;:27:::2;::::0;::::2;::::0;;;;;;;:38;:51:::2;::::0;52287:7;52244:42:::2;:51::i;:::-;52213:10;52203:21;::::0;;;:9:::2;:21;::::0;;;;;;;:27:::2;::::0;::::2;::::0;;;;;;;:92;;;;:21;52363:16:::2;::::0;:22:::2;::::0;::::2;;;;;;;;:39;;;:43;52359:304;;;52549:16;52566:4;52549:22;;;;;;;;;;;;:39;;::::0;52517:10:::2;52507:21;::::0;;;:9:::2;:21;::::0;;;;;;;:27:::2;::::0;::::2;::::0;;;;;;;:38;:81:::2;;52481:170;;;::::0;;-1:-1:-1;;;52481:170:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;52761:51;52804:7;52761:16;52778:4;52761:22;;;;;;;;;;;;:38;;;:42;;:51;;;;:::i;:::-;52720:16;52737:4;52720:22;;;;;;;;;;;;:38;;:92;;;;52850:4;52830:34;;52838:10;-1:-1:-1::0;;;;;52830:34:0::2;;52856:7;52830:34;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;1679:1:0;2641:7;:22;-1:-1:-1;;50700:2172:0:o;46338:37::-;46374:1;46338:37;:::o;46278:27::-;;;-1:-1:-1;;;;;46278:27:0;;:::o;65222:491::-;65336:7;46374:1;65364:18;;;;65356:50;;;;;-1:-1:-1;;;65356:50:0;;;;;;;;;;;;-1:-1:-1;;;65356:50:0;;;;;;;;;;;;;;;65417:35;;:::i;:::-;65455:16;65472:4;65455:22;;;;;;;;;65417:60;;;;;;;;65455:22;;;;;;;;;65417:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65494:101:0;;65558:26;;65542:43;;-1:-1:-1;;65550:2:0;65542:15;:43::i;:::-;65535:50;;;;;65494:101;65612:93;65680:8;:24;;;65613:61;65670:3;65613:52;65638:8;:26;;;65613:8;:20;;;:24;;:52;;;;:::i;:::-;:56;;:61::i;:::-;65612:67;;:93::i;:::-;65605:100;65222:491;-1:-1:-1;;;65222:491:0:o;64161:912::-;64321:19;;64409:5;64392:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;64358:64;;64440:7;64435:602;64453:16;;;;-1:-1:-1;64435:602:0;;;64491:30;64536:31;64582:25;64675:1;64628:16;64645:5;;64651:1;64645:8;;;;;;;;;;;;;;;;;64628:26;;;;;;;;;;;;:44;:48;64624:300;;;64850:58;64892:5;64899;;64905:1;64899:8;;;;;;;;;;;;;;;;;64850:41;:58::i;:::-;64697:211;;-1:-1:-1;64697:211:0;-1:-1:-1;64697:211:0;-1:-1:-1;64624:300:0;64940:85;;;;;;;;64958:22;64940:85;;;;64982:23;64940:85;;;;65007:17;64940:85;;;:11;64952:1;64940:14;;;;;;;;;;;;;;;;;;;:85;-1:-1:-1;;;64471:3:0;;64435:602;;;-1:-1:-1;65054:11:0;64161:912;-1:-1:-1;;;;64161:912:0:o;29109:244::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;29198:22:0;::::1;29190:73;;;;-1:-1:-1::0;;;29190:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29300:6;::::0;29279:38:::1;::::0;-1:-1:-1;;;;;29279:38:0;;::::1;::::0;29300:6:::1;::::0;29279:38:::1;::::0;29300:6:::1;::::0;29279:38:::1;29328:6;:17:::0;;-1:-1:-1;;;;;;29328:17:0::1;-1:-1:-1::0;;;;;29328:17:0;;;::::1;::::0;;;::::1;::::0;;29109:244::o;57383:1156::-;28386:12;:10;:12::i;:::-;-1:-1:-1;;;;;28375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;28375:23:0;;28367:68;;;;;-1:-1:-1;;;28367:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;28367:68:0;;;;;;;;;;;;;;;57715:10:::1;;57700:12;:25;57692:53;;;::::0;;-1:-1:-1;;;57692:53:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;57692:53:0;;;;;;;;;;;;;::::1;;46374:1;57764:18;::::0;::::1;;57756:50;;;::::0;;-1:-1:-1;;;57756:50:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;57756:50:0;;;;;;;;;;;;;::::1;;57823:15;57819:103;;;57877:3;57861:12;:19;;57853:57;;;::::0;;-1:-1:-1;;;57853:57:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;57976:19;57932:16;57949:4;57932:22;;;;;;;;;;;;:41;;:63;;;;58049:18;58006:16;58023:4;58006:22;;;;;;;;;;;;:61:::0;58120:17;58078:16:::1;:22;::::0;::::1;;::::0;::::1;;;;;;;;:39;;:59;;;;58180:7;58148:16;58165:4;58148:22;;;;;;;;;;;;:29;;;:39;;;;;;;;;;;;;;;;;;58238:15;58198:16;58215:4;58198:22;;;;;;;;;;;;:37;;;:55;;;;;;;;;;;;;;;;;;58301:12;58264:16;58281:4;58264:22;;;;;;;;;;;;:34;;:49;;;;58362:13;58324:16;58341:4;58324:22;;;;;;;;;;;;:35;;:51:::0;;-1:-1:-1;;58324:51:0::1;::::0;::::1;;::::0;;;::::1;::::0;;58393:138:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;::::1;;::::0;;;;;::::1;;::::0;;;;;;;;;;;::::1;;::::0;;;;;;58324:51:::1;58393:138:::0;::::1;::::0;::::1;::::0;;;;;;;;;;;::::1;57383:1156:::0;;;;;;;;:::o;63039:211::-;63184:4;63206:36;63221:5;63228:4;63235:6;;63206:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63206:14:0;;-1:-1:-1;;;63206:36:0:i;:::-;63199:43;63039:211;-1:-1:-1;;;;;63039:211:0:o;62303:415::-;62443:16;;62526:5;62512:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62512:27:0;;62477:62;;62555:7;62550:128;62568:16;;;;-1:-1:-1;62550:128:0;;;62627:39;62650:5;62657;;62663:1;62657:8;;;;;;;;;;;;;;;;;62627:22;:39::i;:::-;62606:15;62622:1;62606:18;;;;;;;;;;;;;;;;;;;:60;62586:3;;62550:128;;71623:193;71754:18;71800:8;;;71623:193::o;67309:2056::-;67451:7;67473;67495;67530:26;67567:27;67605:17;67680:16;67697:4;67680:22;;;;;;;;;;;;:40;67639:16;:22;;;;;;;;;;;;;:38;;;:81;67635:1653;;;67787:18;67808:35;67831:5;67838:4;67808:22;:35::i;:::-;67787:56;;67981:67;68043:4;67981:57;68027:10;67981:16;67998:4;67981:22;;;;;;;;;;;;:41;;;:45;;:57;;;;:::i;:67::-;67960:88;;68105:17;68125:66;68186:4;68125:56;68170:10;68125:16;68142:4;68125:22;;;;;;;;;;;;:40;;:44;:56::i;:66::-;-1:-1:-1;;;;;68285:16:0;;;;;;:9;:16;;;;;;;;:22;;;;;;;;;;:33;68105:86;;-1:-1:-1;68285:48:0;;68105:86;68285:37;:48::i;:::-;68263:70;;68392:16;68409:4;68392:22;;;;;;;;;;;;:29;;;;;68388:543;;;68442:19;68485:176;68533:16;68550:4;68533:22;;;;;;;;;;;;:38;;;68598:16;68615:4;68598:22;;;;;;;;68485:176;68442:219;-1:-1:-1;68744:46:0;68785:4;68744:36;:19;68442:219;68744:23;:36::i;:46::-;68732:58;-1:-1:-1;68881:34:0;:19;68732:58;68881:23;:34::i;:::-;68859:56;;68388:543;;67635:1653;;;;;-1:-1:-1;68985:1:0;;-1:-1:-1;68985:1:0;69118:158;69221:16;:22;;;;;;;;;;;;;:40;69118:80;69156:16;:22;;;;;;;;;;;;;:41;;;-1:-1:-1;;;;;69118:16:0;;;;;;:9;:16;;;;;;;;:22;;;;;;;;;;:33;;:37;:80::i;:158::-;69097:179;;67635:1653;69306:18;;-1:-1:-1;69326:19:0;-1:-1:-1;69347:9:0;-1:-1:-1;67309:2056:0;;;;;:::o;6766:179::-;6824:7;6856:5;;;6880:6;;;;6872:46;;;;;-1:-1:-1;;;6872:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6936:1;-1:-1:-1;6766:179:0;;;;;:::o;22965:177::-;23075:58;;;-1:-1:-1;;;;;23075:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23075:58:0;-1:-1:-1;;;23075:58:0;;;23048:86;;23068:5;;23048:19;:86::i;:::-;22965:177;;;:::o;66332:630::-;66467:7;;66516:40;:16;66537:18;66516:20;:40::i;:::-;66492:64;;66590:3;66573:13;:20;66569:386;;66617:10;66610:17;;;;;66569:386;66674:3;66657:13;:20;66653:302;;66701:10;66694:17;;;;;66653:302;66759:2;66742:13;:19;66738:217;;66785:10;66778:17;;;;;66738:217;66842:2;66825:13;:19;66821:134;;66868:10;66861:17;;;;;66821:134;66926:11;66919:18;;;;;26682:106;26770:10;26682:106;:::o;71031:516::-;71097:4;46374:1;71120:18;;;;71112:50;;;;;-1:-1:-1;;;71112:50:0;;;;;;;;;;;;-1:-1:-1;;;71112:50:0;;;;;;;;;;;;;;;71204:16;71221:4;71204:22;;;;;;;;;;;;:37;;;;;71199:77;;-1:-1:-1;71261:5:0;71254:12;;71199:77;71351:21;71375:95;71429:16;71446:4;71429:22;;;;;;;;;;;;:40;71375:49;71420:3;71376:16;:22;;;;;;;;;;;;;:38;;;71375:44;;:49;;;;:::i;:95::-;71351:119;;71505:16;71522:4;71505:22;;;;;;;;;;;;:34;;;71488:13;:51;;71481:58;;;71031:516;;;:::o;69689:523::-;69791:4;46374:1;69814:18;;;;69806:50;;;;;-1:-1:-1;;;69806:50:0;;;;;;;;;;;;-1:-1:-1;;;69806:50:0;;;;;;;;;;;;;;;69872:16;69889:4;69872:22;;;;;;;;;;;;:35;;;;;69867:74;;-1:-1:-1;69927:4:0;69920:11;;69867:74;69959:16;69976:4;69959:22;;;;;;;;;;;;:33;;;69996:1;69959:38;;;;69951:71;;;;;-1:-1:-1;;;69951:71:0;;;;;;;;;;;;-1:-1:-1;;;69951:71:0;;;;;;;;;;;;;;;70092:26;;;-1:-1:-1;;70092:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70082:37;;;;;70137:67;70156:6;70164:16;:22;;;;;;;;;;;;;:33;;;70199:4;70137:18;:67::i;23150:205::-;23278:68;;;-1:-1:-1;;;;;23278:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23278:68:0;-1:-1:-1;;;23278:68:0;;;23251:96;;23271:5;;23251:19;:96::i;:::-;23150:205;;;;:::o;7228:158::-;7286:7;7319:1;7314;:6;;7306:49;;;;;-1:-1:-1;;;7306:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7373:5:0;;;7228:158::o;7645:220::-;7703:7;7727:6;7723:20;;-1:-1:-1;7742:1:0;7735:8;;7723:20;7766:5;;;7770:1;7766;:5;:1;7790:5;;;;;:10;7782:56;;;;-1:-1:-1;;;7782:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8343:153;8401:7;8433:1;8429;:5;8421:44;;;;;-1:-1:-1;;;8421:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;8487:1;8483;:5;;;;;;;8343:153;-1:-1:-1;;;8343:153:0:o;70529:328::-;70611:7;70676:1;70635:16;70652:4;70635:22;;;;;;;;;;;;:38;;;:42;70631:219;;;70701:96;70749:47;70792:3;70749:16;70766:4;70749:22;;;;;;;;:47;-1:-1:-1;;;;;70701:16:0;;;;;;:9;:16;;;;;;;;:22;;;;;;;;;;:33;:43;;70739:4;70701:37;:43::i;:96::-;70694:103;;;;70631:219;-1:-1:-1;70837:1:0;70830:8;;25270:761;25694:23;25720:69;25748:4;25720:69;;;;;;;;;;;;;;;;;25728:5;-1:-1:-1;;;;;25720:27:0;;;:69;;;;;:::i;:::-;25804:17;;25694:95;;-1:-1:-1;25804:21:0;25800:224;;25946:10;25935:30;;;;;;;;;;;;;;;-1:-1:-1;25935:30:0;25927:85;;;;-1:-1:-1;;;25927:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3164:796;3255:4;3295;3255;3312:525;3336:5;:12;3332:1;:16;3312:525;;;3370:20;3393:5;3399:1;3393:8;;;;;;;;;;;;;;3370:31;;3438:12;3422;:28;3418:408;;3592:12;3606;3575:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3565:55;;;;;;3550:70;;3418:408;;;3782:12;3796;3765:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3755:55;;;;;;3740:70;;3418:408;-1:-1:-1;3350:3:0;;3312:525;;;-1:-1:-1;3932:20:0;;;;3164:796;-1:-1:-1;;;3164:796:0:o;17952:195::-;18055:12;18087:52;18109:6;18117:4;18123:1;18126:12;18087:21;:52::i;:::-;18080:59;17952:195;-1:-1:-1;;;;17952:195:0:o;19004:530::-;19131:12;19189:5;19164:21;:30;;19156:81;;;;-1:-1:-1;;;19156:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19256:18;19267:6;19256:10;:18::i;:::-;19248:60;;;;;-1:-1:-1;;;19248:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;19382:12;19396:23;19423:6;-1:-1:-1;;;;;19423:11:0;19443:5;19451:4;19423:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;19423:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19381:75;;;;19474:52;19492:7;19501:10;19513:12;19474:17;:52::i;:::-;19467:59;19004:530;-1:-1:-1;;;;;;;19004:530:0:o;21544:742::-;21659:12;21688:7;21684:595;;;-1:-1:-1;21719:10:0;21712:17;;21684:595;21833:17;;:21;21829:439;;22096:10;22090:17;22157:15;22144:10;22140:2;22136:19;22129:44;22044:148;22239:12;22232:20;;-1:-1:-1;;;22232:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://46a2cbab5d7df1d2dafb9f625a21deeb768bf1703065d24a4136cce7e7cd0766
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.