Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PopMarketplace
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-05-05
*/
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.6;
/**
* @title Initializable
*
* @dev Helper contract to support initializer functions. To use it, replace
* the constructor with a function that has the `initializer` modifier.
* WARNING: Unlike constructors, initializer functions must be manually
* invoked. This applies both to deploying an Initializable contract, as well
* as extending an Initializable contract via inheritance.
* WARNING: When used with inheritance, manual care must be taken to not invoke
* a parent initializer twice, or ensure that all initializers are idempotent,
* because this is not dealt with automatically as with constructors.
*/
contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
address self = address(this);
uint256 cs;
assembly {
cs := extcodesize(self)
}
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}
/*
* @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.
*/
contract ContextUpgradeSafe is Initializable {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {}
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;
}
uint256[50] private __gap;
}
/**
* @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.
*/
contract OwnableUpgradeSafe is Initializable, ContextUpgradeSafe {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view 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;
}
uint256[49] private __gap;
}
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function price0CumulativeLast() external view returns (uint256);
function price1CumulativeLast() external view returns (uint256);
function kLast() external view returns (uint256);
function mint(address to) external returns (uint256 liquidity);
function burn(address to) external returns (uint256 amount0, uint256 amount1);
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
library SafeMath {
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x, "ds-math-add-overflow");
}
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x, "ds-math-sub-underflow");
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
}
}
library UniswapV2Library {
using SafeMath for uint256;
// returns sorted token addresses, used to handle return values from pairs sorted in this order
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
require(tokenA != tokenB, "UniswapV2Library: IDENTICAL_ADDRESSES");
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), "UniswapV2Library: ZERO_ADDRESS");
}
// calculates the CREATE2 address for a pair without making any external calls
function pairFor(
address factory,
address tokenA,
address tokenB
) internal pure returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
pair = address(
uint256(
keccak256(
abi.encodePacked(
hex"ff",
factory,
keccak256(abi.encodePacked(token0, token1)),
hex"96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f" // init code hash
)
)
)
);
}
// fetches and sorts the reserves for a pair
function getReserves(
address factory,
address tokenA,
address tokenB
) internal view returns (uint256 reserveA, uint256 reserveB) {
(address token0, ) = sortTokens(tokenA, tokenB);
(uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves();
(reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
}
// given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
function quote(
uint256 amountA,
uint256 reserveA,
uint256 reserveB
) internal pure returns (uint256 amountB) {
require(amountA > 0, "UniswapV2Library: INSUFFICIENT_AMOUNT");
require(reserveA > 0 && reserveB > 0, "UniswapV2Library: INSUFFICIENT_LIQUIDITY");
amountB = amountA.mul(reserveB) / reserveA;
}
// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) internal pure returns (uint256 amountOut) {
require(amountIn > 0, "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT");
require(reserveIn > 0 && reserveOut > 0, "UniswapV2Library: INSUFFICIENT_LIQUIDITY");
uint256 amountInWithFee = amountIn.mul(997);
uint256 numerator = amountInWithFee.mul(reserveOut);
uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
// given an output amount of an asset and pair reserves, returns a required input amount of the other asset
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) internal pure returns (uint256 amountIn) {
require(amountOut > 0, "UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT");
require(reserveIn > 0 && reserveOut > 0, "UniswapV2Library: INSUFFICIENT_LIQUIDITY");
uint256 numerator = reserveIn.mul(amountOut).mul(1000);
uint256 denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}
// performs chained getAmountOut calculations on any number of pairs
function getAmountsOut(
address factory,
uint256 amountIn,
address[] memory path
) internal view returns (uint256[] memory amounts) {
require(path.length >= 2, "UniswapV2Library: INVALID_PATH");
amounts = new uint256[](path.length);
amounts[0] = amountIn;
for (uint256 i; i < path.length - 1; i++) {
(uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i], path[i + 1]);
amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
}
}
// performs chained getAmountIn calculations on any number of pairs
function getAmountsIn(
address factory,
uint256 amountOut,
address[] memory path
) internal view returns (uint256[] memory amounts) {
require(path.length >= 2, "UniswapV2Library: INVALID_PATH");
amounts = new uint256[](path.length);
amounts[amounts.length - 1] = amountOut;
for (uint256 i = path.length - 1; i > 0; i--) {
(uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i - 1], path[i]);
amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
}
}
}
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETH(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETHWithPermit(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountToken, uint256 amountETH);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapTokensForExactETH(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapETHForExactTokens(
uint256 amountOut,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function quote(
uint256 amountA,
uint256 reserveA,
uint256 reserveB
) external pure returns (uint256 amountB);
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountOut);
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountIn);
function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);
function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts);
}
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
/**
* @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);
}
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);
}
}
/**
* @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);
}
}
}
}
/**
* @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);
_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");
}
}
}
abstract contract IMlp {
function makeOffer(
address _token,
uint256 _amount,
uint256 _unlockDate,
uint256 _endDate,
uint256 _slippageTolerancePpm,
uint256 _maxPriceVariationPpm
) external virtual returns (uint256 offerId);
function takeOffer(
uint256 _pendingOfferId,
uint256 _amount,
uint256 _deadline
) external virtual returns (uint256 activeOfferId);
function cancelOffer(uint256 _offerId) external virtual;
function release(uint256 _offerId, uint256 _deadline) external virtual;
}
abstract contract IFeesController {
function feesTo() public virtual returns (address);
function setFeesTo(address) public virtual;
function feesPpm() public virtual returns (uint256);
function setFeesPpm(uint256) public virtual;
}
abstract contract IRewardManager {
function add(uint256 _allocPoint, address _newMlp) public virtual;
function notifyDeposit(address _account, uint256 _amount) public virtual;
function notifyWithdraw(address _account, uint256 _amount) public virtual;
function getPoolSupply(address pool) public view virtual returns (uint256);
function getUserAmount(address pool, address user) public view virtual returns (uint256);
}
contract MLP is IMlp {
using SafeERC20 for IERC20;
using SafeMath for uint256;
uint256 public endDate;
address public submitter;
uint256 public exceedingLiquidity;
uint256 public bonusToken0;
uint256 public reward0Rate;
uint256 public reward0PerTokenStored;
uint256 public bonusToken1;
uint256 public reward1Rate;
uint256 public reward1PerTokenStored;
uint256 public lastUpdateTime;
uint256 public pendingOfferCount;
uint256 public activeOfferCount;
IRewardManager public rewardManager;
IUniswapV2Pair public uniswapPair;
IFeesController public feesController;
IUniswapV2Router02 public uniswapRouter;
mapping(address => uint256) public userReward0PerTokenPaid;
mapping(address => uint256) public userRewards0;
mapping(address => uint256) public userReward1PerTokenPaid;
mapping(address => uint256) public userRewards1;
mapping(address => uint256) public directStakeBalances;
mapping(uint256 => PendingOffer) public getPendingOffer;
mapping(uint256 => ActiveOffer) public getActiveOffer;
enum OfferStatus {PENDING, TAKEN, CANCELED}
event OfferMade(uint256 id);
event OfferTaken(uint256 pendingOfferId, uint256 activeOfferId);
event OfferCanceled(uint256 id);
event OfferReleased(uint256 offerId);
struct PendingOffer {
address owner;
address token;
uint256 amount;
uint256 unlockDate;
uint256 endDate;
OfferStatus status;
uint256 slippageTolerancePpm;
uint256 maxPriceVariationPpm;
}
struct ActiveOffer {
address user0;
uint256 originalAmount0;
address user1;
uint256 originalAmount1;
uint256 unlockDate;
uint256 liquidity;
bool released;
uint256 maxPriceVariationPpm;
}
constructor(
address _uniswapPair,
address _submitter,
uint256 _endDate,
address _uniswapRouter,
address _feesController,
IRewardManager _rewardManager,
uint256 _bonusToken0,
uint256 _bonusToken1
) public {
feesController = IFeesController(_feesController);
uniswapPair = IUniswapV2Pair(_uniswapPair);
endDate = _endDate;
submitter = _submitter;
uniswapRouter = IUniswapV2Router02(_uniswapRouter);
rewardManager = _rewardManager;
uint256 remainingTime = _endDate.sub(block.timestamp);
bonusToken0 = _bonusToken0;
reward0Rate = _bonusToken0 / remainingTime;
bonusToken1 = _bonusToken1;
reward1Rate = _bonusToken1 / remainingTime;
lastUpdateTime = block.timestamp;
}
function lastTimeRewardApplicable() public view returns (uint256) {
return Math.min(block.timestamp, endDate);
}
function reward0PerToken() public view returns (uint256) {
uint256 totalSupply = rewardManager.getPoolSupply(address(this));
if (totalSupply == 0) {
return reward0PerTokenStored;
}
return reward0PerTokenStored.add(lastTimeRewardApplicable().sub(lastUpdateTime).mul(reward0Rate).mul(1e18) / totalSupply);
}
function reward1PerToken() public view returns (uint256) {
uint256 totalSupply = rewardManager.getPoolSupply(address(this));
if (totalSupply == 0) {
return reward1PerTokenStored;
}
return reward1PerTokenStored.add(lastTimeRewardApplicable().sub(lastUpdateTime).mul(reward1Rate).mul(1e18) / totalSupply);
}
function rewardEarned(address account) public view returns (uint256 reward0Earned, uint256 reward1Earned) {
uint256 balance = rewardManager.getUserAmount(address(this), account);
reward0Earned = (balance.mul(reward0PerToken().sub(userReward0PerTokenPaid[account])) / 1e18).add(userRewards0[account]);
reward1Earned = (balance.mul(reward1PerToken().sub(userReward1PerTokenPaid[account])) / 1e18).add(userRewards1[account]);
}
function updateRewards(address account) internal {
reward0PerTokenStored = reward0PerToken();
reward1PerTokenStored = reward1PerToken();
lastUpdateTime = lastTimeRewardApplicable();
if (account != address(0)) {
(uint256 earned0, uint256 earned1) = rewardEarned(account);
userRewards0[account] = earned0;
userRewards1[account] = earned1;
userReward0PerTokenPaid[account] = reward0PerTokenStored;
userReward1PerTokenPaid[account] = reward1PerTokenStored;
}
}
function payRewards(address account) public {
updateRewards(account);
(uint256 reward0, uint256 reward1) = rewardEarned(account);
if (reward0 > 0) {
userRewards0[account] = 0;
IERC20(uniswapPair.token0()).safeTransfer(account, reward0);
}
if (reward1 > 0) {
userRewards1[account] = 0;
IERC20(uniswapPair.token1()).safeTransfer(account, reward1);
}
}
function _notifyDeposit(address account, uint256 amount) internal {
updateRewards(account);
rewardManager.notifyDeposit(account, amount);
}
function _notifyWithdraw(address account, uint256 amount) internal {
updateRewards(account);
rewardManager.notifyWithdraw(account, amount);
}
function makeOffer(
address _token,
uint256 _amount,
uint256 _unlockDate,
uint256 _endDate,
uint256 _slippageTolerancePpm,
uint256 _maxPriceVariationPpm
) external override returns (uint256 offerId) {
require(_amount > 0);
require(_endDate > now);
require(_endDate <= _unlockDate);
offerId = pendingOfferCount;
pendingOfferCount++;
getPendingOffer[offerId] = PendingOffer(
msg.sender,
_token,
_amount,
_unlockDate,
_endDate,
OfferStatus.PENDING,
_slippageTolerancePpm,
_maxPriceVariationPpm
);
IERC20 token;
if (_token == address(uniswapPair.token0())) {
token = IERC20(uniswapPair.token0());
} else if (_token == address(uniswapPair.token1())) {
token = IERC20(uniswapPair.token1());
} else {
require(false, "unknown token");
}
token.safeTransferFrom(msg.sender, address(this), _amount);
emit OfferMade(offerId);
}
struct ProviderInfo {
address user;
uint256 amount;
IERC20 token;
}
struct OfferInfo {
uint256 deadline;
uint256 slippageTolerancePpm;
}
function takeOffer(
uint256 _pendingOfferId,
uint256 _amount,
uint256 _deadline
) external override returns (uint256 activeOfferId) {
PendingOffer storage pendingOffer = getPendingOffer[_pendingOfferId];
require(pendingOffer.status == OfferStatus.PENDING);
require(pendingOffer.endDate > now);
pendingOffer.status = OfferStatus.TAKEN;
// Sort the users, tokens, and amount
ProviderInfo memory provider0;
ProviderInfo memory provider1;
{
if (pendingOffer.token == uniswapPair.token0()) {
provider0 = ProviderInfo(pendingOffer.owner, pendingOffer.amount, IERC20(uniswapPair.token0()));
provider1 = ProviderInfo(msg.sender, _amount, IERC20(uniswapPair.token1()));
provider1.token.safeTransferFrom(provider1.user, address(this), provider1.amount);
} else {
provider0 = ProviderInfo(msg.sender, _amount, IERC20(uniswapPair.token0()));
provider1 = ProviderInfo(pendingOffer.owner, pendingOffer.amount, IERC20(uniswapPair.token1()));
provider0.token.safeTransferFrom(provider0.user, address(this), provider0.amount);
}
}
// calculate fees
uint256 feesAmount0 = provider0.amount.mul(feesController.feesPpm()) / 1000;
uint256 feesAmount1 = provider1.amount.mul(feesController.feesPpm()) / 1000;
// take fees
provider0.amount = provider0.amount.sub(feesAmount0);
provider1.amount = provider1.amount.sub(feesAmount1);
// send fees
provider0.token.safeTransfer(feesController.feesTo(), feesAmount0);
provider1.token.safeTransfer(feesController.feesTo(), feesAmount1);
uint256 spentAmount0;
uint256 spentAmount1;
uint256 liquidity;
uint256[] memory returnedValues = new uint256[](3);
// send tokens to uniswap
{
returnedValues = _provideLiquidity(provider0, provider1, OfferInfo(_deadline, pendingOffer.slippageTolerancePpm));
liquidity = returnedValues[0];
spentAmount0 = returnedValues[1];
spentAmount1 = returnedValues[2];
}
// stake liquidity
_notifyDeposit(provider0.user, liquidity / 2);
_notifyDeposit(provider1.user, liquidity / 2);
if (liquidity % 2 != 0) {
exceedingLiquidity = exceedingLiquidity.add(1);
}
// Record the active offer
activeOfferId = activeOfferCount;
activeOfferCount++;
getActiveOffer[activeOfferId] = ActiveOffer(
provider0.user,
spentAmount0,
provider1.user,
spentAmount1,
pendingOffer.unlockDate,
liquidity,
false,
pendingOffer.maxPriceVariationPpm
);
emit OfferTaken(_pendingOfferId, activeOfferId);
return activeOfferId;
}
function _provideLiquidity(
ProviderInfo memory _provider0,
ProviderInfo memory _provider1,
OfferInfo memory _info
) internal returns (uint256[] memory) {
_provider0.token.safeApprove(address(uniswapRouter), 0);
_provider1.token.safeApprove(address(uniswapRouter), 0);
_provider0.token.safeApprove(address(uniswapRouter), _provider0.amount);
_provider1.token.safeApprove(address(uniswapRouter), _provider1.amount);
uint256 amountMin0 = _provider0.amount.sub(_provider0.amount.mul(_info.slippageTolerancePpm) / 1000);
uint256 amountMin1 = _provider1.amount.sub(_provider1.amount.mul(_info.slippageTolerancePpm) / 1000);
// Add the liquidity to Uniswap
uint256 spentAmount0;
uint256 spentAmount1;
uint256 liquidity;
{
(spentAmount0, spentAmount1, liquidity) = uniswapRouter.addLiquidity(
address(_provider0.token),
address(_provider1.token),
_provider0.amount,
_provider1.amount,
amountMin0,
amountMin1,
address(this),
_info.deadline
);
}
// Give back the exceeding tokens
if (spentAmount0 < _provider0.amount) {
_provider0.token.safeTransfer(_provider0.user, _provider0.amount - spentAmount0);
}
if (spentAmount1 < _provider1.amount) {
_provider1.token.safeTransfer(_provider1.user, _provider1.amount - spentAmount1);
}
uint256[] memory liq = new uint256[](3);
liq[0] = liquidity;
liq[1] = spentAmount0;
liq[2] = spentAmount1;
return (liq);
}
function cancelOffer(uint256 _offerId) external override {
PendingOffer storage pendingOffer = getPendingOffer[_offerId];
require(pendingOffer.status == OfferStatus.PENDING);
pendingOffer.status = OfferStatus.CANCELED;
IERC20(pendingOffer.token).safeTransfer(pendingOffer.owner, pendingOffer.amount);
emit OfferCanceled(_offerId);
}
function release(uint256 _offerId, uint256 _deadline) external override {
ActiveOffer storage offer = getActiveOffer[_offerId];
require(msg.sender == offer.user0 || msg.sender == offer.user1, "unauthorized");
require(now > offer.unlockDate, "locked");
require(!offer.released, "already released");
offer.released = true;
IERC20 token0 = IERC20(uniswapPair.token0());
IERC20 token1 = IERC20(uniswapPair.token1());
IERC20(address(uniswapPair)).safeApprove(address(uniswapRouter), 0);
IERC20(address(uniswapPair)).safeApprove(address(uniswapRouter), offer.liquidity);
(uint256 amount0, uint256 amount1) = uniswapRouter.removeLiquidity(address(token0), address(token1), offer.liquidity, 0, 0, address(this), _deadline);
_notifyWithdraw(offer.user0, offer.liquidity / 2);
_notifyWithdraw(offer.user1, offer.liquidity / 2);
if (_getPriceVariation(offer.originalAmount0, amount0) > offer.maxPriceVariationPpm) {
if (amount0 > offer.originalAmount0) {
uint256 toSwap = amount0.sub(offer.originalAmount0);
address[] memory path = new address[](2);
path[0] = uniswapPair.token0();
path[1] = uniswapPair.token1();
token0.safeApprove(address(uniswapRouter), 0);
token0.safeApprove(address(uniswapRouter), toSwap);
uint256[] memory newAmounts = uniswapRouter.swapExactTokensForTokens(toSwap, 0, path, address(this), _deadline);
amount0 = amount0.sub(toSwap);
amount1 = amount1.add(newAmounts[1]);
}
}
if (_getPriceVariation(offer.originalAmount1, amount1) > offer.maxPriceVariationPpm) {
if (amount1 > offer.originalAmount1) {
uint256 toSwap = amount1.sub(offer.originalAmount1);
address[] memory path = new address[](2);
path[0] = uniswapPair.token1();
path[1] = uniswapPair.token0();
token1.safeApprove(address(uniswapRouter), 0);
token1.safeApprove(address(uniswapRouter), toSwap);
uint256[] memory newAmounts = uniswapRouter.swapExactTokensForTokens(toSwap, 0, path, address(this), _deadline);
amount1 = amount1.sub(toSwap);
amount0 = amount0.add(newAmounts[1]);
}
}
token0.safeTransfer(offer.user0, amount0);
payRewards(offer.user0);
token1.safeTransfer(offer.user1, amount1);
payRewards(offer.user1);
emit OfferReleased(_offerId);
}
function _getPriceVariation(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 sub;
if (a > b) {
sub = a.sub(b);
return sub.mul(1000) / a;
} else {
sub = b.sub(a);
return sub.mul(1000) / b;
}
}
function directStake(uint256 _amount) external {
require(_amount > 0, "cannot stake 0");
_notifyDeposit(msg.sender, _amount);
directStakeBalances[msg.sender] = directStakeBalances[msg.sender].add(_amount);
IERC20(address(uniswapPair)).safeTransferFrom(msg.sender, address(this), _amount);
}
function directWithdraw(uint256 _amount) external {
require(_amount > 0, "cannot withdraw 0");
_notifyWithdraw(msg.sender, _amount);
directStakeBalances[msg.sender] = directStakeBalances[msg.sender].sub(_amount);
IERC20(address(uniswapPair)).safeTransfer(msg.sender, _amount);
}
function transferExceedingLiquidity() external {
require(exceedingLiquidity != 0);
IERC20(address(uniswapPair)).safeTransfer(feesController.feesTo(), exceedingLiquidity);
exceedingLiquidity = 0;
}
}
abstract contract IMintableERC20 is IERC20 {
function mint(uint256 amount) public virtual;
function mintTo(address account, uint256 amount) public virtual;
function burn(uint256 amount) public virtual;
function setMinter(address account, bool isMinter) public virtual;
}
abstract contract IPopMarketplace {
function submitMlp(
address _token0,
address _token1,
uint256 _liquidity,
uint256 _endDate,
uint256 _bonusToken0,
uint256 _bonusToken1
) public virtual returns (uint256);
function endMlp(uint256 _mlpId) public virtual returns (uint256);
function cancelMlp(uint256 _mlpId) public virtual;
}
contract PopMarketplace is IFeesController, IPopMarketplace, Initializable, OwnableUpgradeSafe {
using SafeERC20 for IERC20;
address public uniswapFactory;
address public uniswapRouter;
address[] public allMlp;
address private _feesTo = msg.sender;
uint256 private _feesPpm;
uint256 public pendingMlpCount;
IRewardManager public rewardManager;
IMintableERC20 public popToken;
mapping(uint256 => PendingMlp) public getMlp;
enum MlpStatus {PENDING, APPROVED, CANCELED, ENDED}
struct PendingMlp {
address uniswapPair;
address submitter;
uint256 liquidity;
uint256 endDate;
MlpStatus status;
uint256 bonusToken0;
uint256 bonusToken1;
}
event MlpCreated(uint256 id, address indexed mlp);
event MlpSubmitted(uint256 id);
event MlpCanceled(uint256 id);
event ChangeFeesPpm(uint256 id);
event ChangeFeesTo(address indexed feeTo);
event MlpEnded(uint256 id);
function initialize(
address _popToken,
address _uniswapFactory,
address _uniswapRouter,
address _rewardManager
) public initializer {
OwnableUpgradeSafe.__Ownable_init();
popToken = IMintableERC20(_popToken);
uniswapFactory = _uniswapFactory;
uniswapRouter = _uniswapRouter;
rewardManager = IRewardManager(_rewardManager);
}
function submitMlp(
address _token0,
address _token1,
uint256 _liquidity,
uint256 _endDate,
uint256 _bonusToken0,
uint256 _bonusToken1
) public override returns (uint256) {
require(_endDate > now, "!datenow");
IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(uniswapFactory, _token0, _token1));
require(address(pair) != address(0), "!address0");
if (_liquidity > 0) {
IERC20(address(pair)).safeTransferFrom(msg.sender, address(this), _liquidity);
}
if (_bonusToken0 > 0) {
IERC20(_token0).safeTransferFrom(msg.sender, address(this), _bonusToken0);
}
if (_bonusToken1 > 0) {
IERC20(_token1).safeTransferFrom(msg.sender, address(this), _bonusToken1);
}
if (_token0 != pair.token0()) {
uint256 tmp = _bonusToken0;
_bonusToken0 = _bonusToken1;
_bonusToken1 = tmp;
}
getMlp[pendingMlpCount++] = PendingMlp({
uniswapPair: address(pair),
submitter: msg.sender,
liquidity: _liquidity,
endDate: _endDate,
status: MlpStatus.PENDING,
bonusToken0: _bonusToken0,
bonusToken1: _bonusToken1
});
uint256 mlpId = pendingMlpCount - 1;
emit MlpSubmitted(mlpId);
return mlpId;
}
function approveMlp(uint256 _mlpId, uint256 _allocPoint) external onlyOwner() returns (address mlpAddress) {
PendingMlp storage pendingMlp = getMlp[_mlpId];
require(pendingMlp.status == MlpStatus.PENDING);
MLP newMlp =
new MLP(
pendingMlp.uniswapPair,
pendingMlp.submitter,
pendingMlp.endDate,
uniswapRouter,
address(this),
rewardManager,
pendingMlp.bonusToken0,
pendingMlp.bonusToken1
);
mlpAddress = address(newMlp);
rewardManager.add(_allocPoint, mlpAddress);
allMlp.push(mlpAddress);
IERC20(IUniswapV2Pair(pendingMlp.uniswapPair).token0()).safeTransfer(mlpAddress, pendingMlp.bonusToken0);
IERC20(IUniswapV2Pair(pendingMlp.uniswapPair).token1()).safeTransfer(mlpAddress, pendingMlp.bonusToken1);
pendingMlp.status = MlpStatus.APPROVED;
emit MlpCreated(_mlpId, mlpAddress);
return mlpAddress;
}
function cancelMlp(uint256 _mlpId) public override {
PendingMlp storage pendingMlp = getMlp[_mlpId];
require(pendingMlp.submitter == msg.sender, "!submitter");
require(pendingMlp.status == MlpStatus.PENDING, "!pending");
if (pendingMlp.liquidity > 0) {
IUniswapV2Pair pair = IUniswapV2Pair(pendingMlp.uniswapPair);
IERC20(address(pair)).safeTransfer(pendingMlp.submitter, pendingMlp.liquidity);
}
if (pendingMlp.bonusToken0 > 0) {
IERC20(IUniswapV2Pair(pendingMlp.uniswapPair).token0()).safeTransfer(pendingMlp.submitter, pendingMlp.bonusToken0);
}
if (pendingMlp.bonusToken1 > 0) {
IERC20(IUniswapV2Pair(pendingMlp.uniswapPair).token1()).safeTransfer(pendingMlp.submitter, pendingMlp.bonusToken1);
}
pendingMlp.status = MlpStatus.CANCELED;
emit MlpCanceled(_mlpId);
}
function setFeesTo(address _newFeesTo) public override onlyOwner {
require(_newFeesTo != address(0), "!address0");
_feesTo = _newFeesTo;
emit ChangeFeesTo(_newFeesTo);
}
function feesTo() public override returns (address) {
return _feesTo;
}
function feesPpm() public override returns (uint256) {
return _feesPpm;
}
function setFeesPpm(uint256 _newFeesPpm) public override onlyOwner {
require(_newFeesPpm > 0, "!<0");
_feesPpm = _newFeesPpm;
emit ChangeFeesPpm(_newFeesPpm);
}
function endMlp(uint256 _mlpId) public override returns (uint256) {
PendingMlp storage pendingMlp = getMlp[_mlpId];
require(pendingMlp.submitter == msg.sender, "!submitter");
require(pendingMlp.status == MlpStatus.APPROVED, "!approved");
require(block.timestamp >= pendingMlp.endDate, "not yet ended");
if (pendingMlp.liquidity > 0) {
IUniswapV2Pair pair = IUniswapV2Pair(pendingMlp.uniswapPair);
IERC20(address(pair)).safeTransfer(pendingMlp.submitter, pendingMlp.liquidity);
}
pendingMlp.status = MlpStatus.ENDED;
emit MlpEnded(_mlpId);
return pendingMlp.liquidity;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ChangeFeesPpm","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"feeTo","type":"address"}],"name":"ChangeFeesTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"MlpCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"mlp","type":"address"}],"name":"MlpCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"MlpEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"MlpSubmitted","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"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allMlp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mlpId","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"approveMlp","outputs":[{"internalType":"address","name":"mlpAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mlpId","type":"uint256"}],"name":"cancelMlp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mlpId","type":"uint256"}],"name":"endMlp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feesPpm","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feesTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getMlp","outputs":[{"internalType":"address","name":"uniswapPair","type":"address"},{"internalType":"address","name":"submitter","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"enum PopMarketplace.MlpStatus","name":"status","type":"uint8"},{"internalType":"uint256","name":"bonusToken0","type":"uint256"},{"internalType":"uint256","name":"bonusToken1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_popToken","type":"address"},{"internalType":"address","name":"_uniswapFactory","type":"address"},{"internalType":"address","name":"_uniswapRouter","type":"address"},{"internalType":"address","name":"_rewardManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingMlpCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"popToken","outputs":[{"internalType":"contract IMintableERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardManager","outputs":[{"internalType":"contract IRewardManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFeesPpm","type":"uint256"}],"name":"setFeesPpm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newFeesTo","type":"address"}],"name":"setFeesTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"uint256","name":"_liquidity","type":"uint256"},{"internalType":"uint256","name":"_endDate","type":"uint256"},{"internalType":"uint256","name":"_bonusToken0","type":"uint256"},{"internalType":"uint256","name":"_bonusToken1","type":"uint256"}],"name":"submitMlp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052609a80546001600160a01b0319163317905534801561002257600080fd5b5061535b806100326000396000f3fe60806040523480156200001157600080fd5b5060043610620001725760003560e01c80638ace113011620000e1578063f2fde38b116200008d578063fa8e39b2116200006f578063fa8e39b214620003a4578063fafd267814620003ae578063fbef7eb714620003b85762000172565b8063f2fde38b146200033a578063f8c8765e14620003635762000172565b80638da5cb5b11620000c35780638da5cb5b14620002f0578063e16fc60b14620002fa578063e402aa1b146200031a5762000172565b80638ace113014620002dc5780638bdb2afa14620002e65762000172565b806343eabd241162000141578063715018a61162000123578063715018a614620002a8578063735de9f714620002b2578063753c7d5214620002bc5762000172565b806343eabd2414620002665780636103341d146200028c5762000172565b80630f4ef8a614620001775780632b261e85146200019d5780633be273a914620001bf57806340fbe74f146200023d575b600080fd5b6200018162000403565b604080516001600160a01b039092168252519081900360200190f35b620001bd60048036036020811015620001b557600080fd5b503562000412565b005b620001df60048036036020811015620001d757600080fd5b50356200069a565b60405180886001600160a01b03168152602001876001600160a01b031681526020018681526020018581526020018460038111156200021a57fe5b815260200183815260200182815260200197505050505050505060405180910390f35b620001bd600480360360208110156200025557600080fd5b50356001600160a01b0316620006e7565b62000181600480360360408110156200027e57600080fd5b508035906020013562000812565b6200029662000b6b565b60408051918252519081900360200190f35b620001bd62000b71565b6200018162000c40565b6200018160048036036020811015620002d457600080fd5b503562000c4f565b6200029662000c77565b6200018162000c7d565b6200018162000c8c565b620001bd600480360360208110156200031257600080fd5b503562000c9b565b62000296600480360360208110156200033257600080fd5b503562000d99565b620001bd600480360360208110156200035257600080fd5b50356001600160a01b031662000f4e565b620001bd600480360360808110156200037b57600080fd5b506001600160a01b03813581169160208101358216916040820135811691606001351662001076565b6200018162001190565b620001816200119f565b62000296600480360360c0811015620003d057600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a00135620011ae565b609d546001600160a01b031681565b6000818152609f6020526040902060018101546001600160a01b0316331462000482576040805162461bcd60e51b815260206004820152600a60248201527f217375626d697474657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000600482015460ff1660038111156200049857fe5b14620004eb576040805162461bcd60e51b815260206004820152600860248201527f2170656e64696e67000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60028101541562000520578054600182015460028301546001600160a01b03928316926200051e928492911690620014ad565b505b600581015415620005d957600181015460058201548254604080517f0dfe16810000000000000000000000000000000000000000000000000000000081529051620005d9946001600160a01b0390811694931691630dfe1681916004808301926020929190829003018186803b1580156200059a57600080fd5b505afa158015620005af573d6000803e3d6000fd5b505050506040513d6020811015620005c657600080fd5b50516001600160a01b03169190620014ad565b6006810154156200065357600181015460068201548254604080517fd21220a7000000000000000000000000000000000000000000000000000000008152905162000653946001600160a01b039081169493169163d21220a7916004808301926020929190829003018186803b1580156200059a57600080fd5b60048101805460ff191660021790556040805183815290517f3fe7c3ab7390584695c5228248ba66ebfb589b7d019e8dfcf410de8b58c6d3da916020908290030190a15050565b609f6020526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b039586169695909416949293919260ff9091169187565b620006f162001534565b6065546001600160a01b0390811691161462000754576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116620007b0576040805162461bcd60e51b815260206004820152600960248201527f2161646472657373300000000000000000000000000000000000000000000000604482015290519081900360640190fd5b609a80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f598c2941e1d126a56daa8263b130d6972c6914f8b3dbffe165eba3ee763ddb0b90600090a250565b60006200081e62001534565b6065546001600160a01b0390811691161462000881576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000838152609f6020526040812090600482015460ff166003811115620008a457fe5b14620008af57600080fd5b805460018201546003830154609854609d54600586015460068701546040516000976001600160a01b03908116978116969581169430949116929091620008f69062001d26565b6001600160a01b03988916815296881660208801526040808801969096529387166060870152918616608086015290941660a084015260c083019390935260e082019290925290519081900361010001906000f0801580156200095d573d6000803e3d6000fd5b50609d54604080517f2b8bbbe8000000000000000000000000000000000000000000000000000000008152600481018890526001600160a01b0380851660248301529151939650869450911691632b8bbbe89160448082019260009290919082900301818387803b158015620009d257600080fd5b505af1158015620009e7573d6000803e3d6000fd5b5050609980546001810182556000919091527f72a152ddfb8e864297c917af52ea6c1c68aead0fee1a62673fcc7e0c94979d000180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038781169190911790915560058501548554604080517f0dfe1681000000000000000000000000000000000000000000000000000000008152905162000ab8965089955092939190911691630dfe168191600480820192602092909190829003018186803b1580156200059a57600080fd5b62000b138383600601548460000160009054906101000a90046001600160a01b03166001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156200059a57600080fd5b600482018054600160ff199091161790556040805186815290516001600160a01b038516917f53dfc5dfee17ca6c290225be486789855a8181f7657a8136faa2ad53105858df919081900360200190a2505092915050565b609c5481565b62000b7b62001534565b6065546001600160a01b0390811691161462000bde576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6098546001600160a01b031681565b6099818154811062000c5d57fe5b6000918252602090912001546001600160a01b0316905081565b609b5490565b6097546001600160a01b031681565b6065546001600160a01b031690565b62000ca562001534565b6065546001600160a01b0390811691161462000d08576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000811162000d5e576040805162461bcd60e51b815260206004820152600360248201527f213c300000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b609b8190556040805182815290517f77ea96a8e905a231dc727a60298571c14e8380d3d55452178b3294ad914de7919181900360200190a150565b6000818152609f6020526040812060018101546001600160a01b0316331462000e09576040805162461bcd60e51b815260206004820152600a60248201527f217375626d697474657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600482015460ff16600381111562000e1f57fe5b1462000e72576040805162461bcd60e51b815260206004820152600960248201527f21617070726f7665640000000000000000000000000000000000000000000000604482015290519081900360640190fd5b806003015442101562000ecc576040805162461bcd60e51b815260206004820152600d60248201527f6e6f742079657420656e64656400000000000000000000000000000000000000604482015290519081900360640190fd5b60028101541562000f01578054600182015460028301546001600160a01b039283169262000eff928492911690620014ad565b505b60048101805460ff191660031790556040805184815290517fdeddae43b7a8a81e62d60690552663f8f21bbb7530e99d6e6dc9e9ed22419c5a916020908290030190a16002015492915050565b62000f5862001534565b6065546001600160a01b0390811691161462000fbb576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116620010025760405162461bcd60e51b81526004018080602001828103825260268152602001806200525d6026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600054610100900460ff16806200109257506200109262001538565b80620010a1575060005460ff16155b620010de5760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff161580156200110a576000805460ff1961ff0019909116610100171660011790555b620011146200153e565b609e80546001600160a01b038088167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556097805487841690831617905560988054868416908316179055609d805492851692909116919091179055801562001189576000805461ff00191690555b5050505050565b609a546001600160a01b031690565b609e546001600160a01b031681565b600042841162001205576040805162461bcd60e51b815260206004820152600860248201527f21646174656e6f77000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60975460009062001221906001600160a01b03168989620015fc565b90506001600160a01b0381166200127f576040805162461bcd60e51b815260206004820152600960248201527f2161646472657373300000000000000000000000000000000000000000000000604482015290519081900360640190fd5b85156200129d576200129d6001600160a01b038216333089620016e9565b8315620012bb57620012bb6001600160a01b038916333087620016e9565b8215620012d957620012d96001600160a01b038816333086620016e9565b806001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156200131357600080fd5b505afa15801562001328573d6000803e3d6000fd5b505050506040513d60208110156200133f57600080fd5b50516001600160a01b0389811691161462001358579192915b6040805160e0810182526001600160a01b0383811682523360208084019182528385018b8152606085018b815260006080870181815260a088018d905260c088018c9052609c805460018082019092558352609f909552979020865181549087167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216178255945181850180549190971695169490941790945551600283015591516003808301919091559351600482018054949592949193909260ff199092169184908111156200142857fe5b021790555060a0820151600582015560c090910151600690910155609c54604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909201808352905190917f1a5c43890324b09ae17af9bd2146b2ef30a3d51d30472357b87bc707e85f8d33919081900360200190a198975050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526200152f90849062001779565b505050565b3390565b303b1590565b600054610100900460ff16806200155a57506200155a62001538565b8062001569575060005460ff16155b620015a65760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff16158015620015d2576000805460ff1961ff0019909116610100171660011790555b620015dc62001830565b620015e6620018d8565b8015620015f9576000805461ff00191690555b50565b60008060006200160d8585620019f3565b604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526200177390859062001779565b50505050565b6060620017d0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662001ad69092919063ffffffff16565b8051909150156200152f57808060200190516020811015620017f157600080fd5b50516200152f5760405162461bcd60e51b815260040180806020018281038252602a815260200180620052fc602a913960400191505060405180910390fd5b600054610100900460ff16806200184c57506200184c62001538565b806200185b575060005460ff16155b620018985760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff16158015620015e6576000805460ff1961ff0019909116610100171660011790558015620015f9576000805461ff001916905550565b600054610100900460ff1680620018f45750620018f462001538565b8062001903575060005460ff16155b620019405760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff161580156200196c576000805460ff1961ff0019909116610100171660011790555b60006200197862001534565b606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015620015f9576000805461ff001916905550565b600080826001600160a01b0316846001600160a01b0316141562001a495760405162461bcd60e51b8152600401808060200182810382526025815260200180620052836025913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b03161062001a6b57828462001a6e565b83835b90925090506001600160a01b03821662001acf576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b9250929050565b606062001ae7848460008562001af1565b90505b9392505050565b60608247101562001b345760405162461bcd60e51b8152600401808060200182810382526026815260200180620052a86026913960400191505060405180910390fd5b62001b3f8562001c76565b62001b91576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831062001bf057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910162001bb1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811462001c54576040519150601f19603f3d011682016040523d82523d6000602084013e62001c59565b606091505b509150915062001c6b82828662001c7c565b979650505050505050565b3b151590565b6060831562001c8d57508162001aea565b82511562001c9e5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101562001cea57818101518382015260200162001cd0565b50505050905090810190601f16801562001d185780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6135288062001d358339019056fe60806040523480156200001157600080fd5b50604051620035283803806200352883398181016040526101008110156200003857600080fd5b50805160208083015160408401516060850151608086015160a087015160c088015160e090980151600e80546001600160a01b03199081166001600160a01b0380871691909117909255600d80548216838c161790556000878155600180548316848b16179055600f80548316848916179055600c8054909216928516929092179055979895979496939592949193909190620000e290889042906200011e811b620027a117901c565b60038490559050808381620000f357fe5b0460045560068290558082816200010657fe5b04600755505042600955506200017d95505050505050565b8082038281111562000177576040805162461bcd60e51b815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b92915050565b61339b806200018d6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638244bd1511610145578063c816841b116100bd578063ef706adf1161008c578063f8dd7c1011610071578063f8dd7c10146105d7578063fa42d8c2146105df578063fabc5a561461060857610241565b8063ef706adf146105b2578063f7e45bc7146105cf57610241565b8063c816841b14610574578063c8f33c911461057c578063e1550fde14610584578063e8f62764146105aa57610241565b80639fc26c3a11610114578063a25b6b0d116100f9578063a25b6b0d1461055c578063c24a0f8b14610564578063c6dbfb8a1461056c57610241565b80639fc26c3a1461052e578063a08363ea1461055457610241565b80638244bd15146104f957806383d490291461051657806387dcec951461051e5780638dc45d9a1461052657610241565b806336e707e8116101d85780636d4af7e9116101a757806377322c371161018c57806377322c37146104e15780637eea237a146104e957806380faa57d146104f157610241565b80636d4af7e914610495578063735de9f7146104d957610241565b806336e707e8146103ab5780633903cc72146103d157806341655ee51461045257806364b3e1531461046f57610241565b806310facdd01161021457806310facdd0146102fb57806316ba6bf314610321578063202e909f14610360578063366a41201461038657610241565b806303a28f4c146102465780630e518506146102605780630eaf1036146102cf5780630f4ef8a6146102d7575b600080fd5b61024e610610565b60408051918252519081900360200190f35b61027d6004803603602081101561027657600080fd5b5035610616565b604080516001600160a01b03998a168152602081019890985295909716868601526060860193909352608085019190915260a0840152151560c083015260e08201929092529051908190036101000190f35b61024e61066b565b6102df610671565b604080516001600160a01b039092168252519081900360200190f35b61024e6004803603602081101561031157600080fd5b50356001600160a01b0316610680565b6103476004803603602081101561033757600080fd5b50356001600160a01b0316610692565b6040805192835260208301919091528051918290030190f35b61024e6004803603602081101561037657600080fd5b50356001600160a01b03166107df565b6103a96004803603604081101561039c57600080fd5b50803590602001356107f1565b005b61024e600480360360208110156103c157600080fd5b50356001600160a01b0316611404565b6103ee600480360360208110156103e757600080fd5b5035611416565b60405180896001600160a01b03168152602001886001600160a01b0316815260200187815260200186815260200185815260200184600281111561042e57fe5b81526020018381526020018281526020019850505050505050505060405180910390f35b6103a96004803603602081101561046857600080fd5b503561146a565b6103a96004803603602081101561048557600080fd5b50356001600160a01b0316611513565b61024e600480360360c08110156104ab57600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a00135611668565b6102df611a50565b61024e611a5f565b61024e611b48565b61024e611b4e565b6103a96004803603602081101561050f57600080fd5b5035611b61565b61024e611c06565b61024e611c0c565b6102df611c12565b61024e6004803603602081101561054457600080fd5b50356001600160a01b0316611c21565b61024e611c33565b6103a9611c39565b61024e611cef565b61024e611cf5565b6102df611cfb565b61024e611d0a565b61024e6004803603602081101561059a57600080fd5b50356001600160a01b0316611d10565b6102df611d22565b6103a9600480360360208110156105c857600080fd5b5035611d31565b61024e611de7565b61024e611ded565b61024e600480360360608110156105f557600080fd5b5080359060208101359060400135611ec9565b61024e61279b565b60055481565b601660205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b039687169795969094169492939192909160ff9091169088565b60045481565b600c546001600160a01b031681565b60136020526000908152604090205481565b600c54604080517f9f1916590000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038481166024830152915160009384938493911691639f19165991604480820192602092909190829003018186803b15801561070457600080fd5b505afa158015610718573d6000803e3d6000fd5b505050506040513d602081101561072e57600080fd5b50516001600160a01b03851660009081526011602090815260408083205460109092529091205491925061079191670de0b6b3a7640000906107839061077c90610776611a5f565b906127a1565b85906127ff565b8161078a57fe5b049061286b565b6001600160a01b0385166000908152601360209081526040808320546012909252909120549194506107d791670de0b6b3a7640000906107839061077c90610776611ded565b915050915091565b60126020526000908152604090205481565b600082815260166020526040902080546001600160a01b0316331480610823575060028101546001600160a01b031633145b610874576040805162461bcd60e51b815260206004820152600c60248201527f756e617574686f72697a65640000000000000000000000000000000000000000604482015290519081900360640190fd5b806004015442116108cc576040805162461bcd60e51b815260206004820152600660248201527f6c6f636b65640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600681015460ff1615610926576040805162461bcd60e51b815260206004820152601060248201527f616c72656164792072656c656173656400000000000000000000000000000000604482015290519081900360640190fd5b6006810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691630dfe1681916004808301926020929190829003018186803b1580156109b157600080fd5b505afa1580156109c5573d6000803e3d6000fd5b505050506040513d60208110156109db57600080fd5b5051600d54604080517fd21220a700000000000000000000000000000000000000000000000000000000815290519293506000926001600160a01b039092169163d21220a791600480820192602092909190829003018186803b158015610a4157600080fd5b505afa158015610a55573d6000803e3d6000fd5b505050506040513d6020811015610a6b57600080fd5b5051600f54600d54919250610a8e916001600160a01b03908116911660006128c3565b600f546005840154600d54610ab1926001600160a01b03918216929116906128c3565b600f546005840154604080517fbaa2abde0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015285811660248301526044820193909352600060648201819052608482018190523060a483015260c48201899052825190948594169263baa2abde9260e4808201939182900301818787803b158015610b4757600080fd5b505af1158015610b5b573d6000803e3d6000fd5b505050506040513d6040811015610b7157600080fd5b50805160209091015186546005880154929450909250610ba1916001600160a01b03909116906002905b04612a1d565b6002808601546005870154610bc2926001600160a01b039092169190610b9b565b8460070154610bd5866001015484612ab0565b1115610f95578460010154821115610f95576000610c008660010154846127a190919063ffffffff16565b6040805160028082526060808301845293945090916020830190803683375050600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290519394506001600160a01b0390911692630dfe168192506004808301926020929190829003018186803b158015610c8157600080fd5b505afa158015610c95573d6000803e3d6000fd5b505050506040513d6020811015610cab57600080fd5b505181518290600090610cba57fe5b6001600160a01b03928316602091820292909201810191909152600d54604080517fd21220a70000000000000000000000000000000000000000000000000000000081529051919093169263d21220a7926004808301939192829003018186803b158015610d2757600080fd5b505afa158015610d3b573d6000803e3d6000fd5b505050506040513d6020811015610d5157600080fd5b5051815182906001908110610d6257fe5b6001600160a01b039283166020918202929092010152600f54610d8b91888116911660006128c3565b600f54610da5906001600160a01b038881169116846128c3565b6060600f60009054906101000a90046001600160a01b03166001600160a01b03166338ed173984600085308e6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015610e41578181015183820152602001610e29565b505050509050019650505050505050600060405180830381600087803b158015610e6a57600080fd5b505af1158015610e7e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015610ec557600080fd5b8101908080516040519392919084640100000000821115610ee557600080fd5b908301906020820185811115610efa57600080fd5b8251866020820283011164010000000082111715610f1757600080fd5b82525081516020918201928201910280838360005b83811015610f44578181015183820152602001610f2c565b505050509050016040525050509050610f6683866127a190919063ffffffff16565b9450610f8f81600181518110610f7857fe5b60200260200101518561286b90919063ffffffff16565b93505050505b8460070154610fa8866003015483612ab0565b1115611368578460030154811115611368576000610fd38660030154836127a190919063ffffffff16565b6040805160028082526060808301845293945090916020830190803683375050600d54604080517fd21220a700000000000000000000000000000000000000000000000000000000815290519394506001600160a01b039091169263d21220a792506004808301926020929190829003018186803b15801561105457600080fd5b505afa158015611068573d6000803e3d6000fd5b505050506040513d602081101561107e57600080fd5b50518151829060009061108d57fe5b6001600160a01b03928316602091820292909201810191909152600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290519190931692630dfe1681926004808301939192829003018186803b1580156110fa57600080fd5b505afa15801561110e573d6000803e3d6000fd5b505050506040513d602081101561112457600080fd5b505181518290600190811061113557fe5b6001600160a01b039283166020918202929092010152600f5461115e91878116911660006128c3565b600f54611178906001600160a01b038781169116846128c3565b6060600f60009054906101000a90046001600160a01b03166001600160a01b03166338ed173984600085308e6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b838110156112145781810151838201526020016111fc565b505050509050019650505050505050600060405180830381600087803b15801561123d57600080fd5b505af1158015611251573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561129857600080fd5b81019080805160405193929190846401000000008211156112b857600080fd5b9083019060208201858111156112cd57600080fd5b82518660208202830111640100000000821117156112ea57600080fd5b82525081516020918201928201910280838360005b838110156113175781810151838201526020016112ff565b50505050905001604052505050905061133983856127a190919063ffffffff16565b93506113628160018151811061134b57fe5b60200260200101518661286b90919063ffffffff16565b94505050505b8454611381906001600160a01b03868116911684612afd565b8454611395906001600160a01b0316611513565b60028501546113b1906001600160a01b03858116911683612afd565b60028501546113c8906001600160a01b0316611513565b6040805188815290517f59a55455fb2332116ca78fe864f670ef66bae65460339946369d37fc255cbdb89181900360200190a150505050505050565b60146020526000908152604090205481565b601560205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b0396871697959096169593949293919260ff9091169188565b600081116114bf576040805162461bcd60e51b815260206004820152600e60248201527f63616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b6114c93382612b7d565b336000908152601460205260409020546114e3908261286b565b33600081815260146020526040902091909155600d54611510916001600160a01b03909116903084612bf4565b50565b61151c81612c82565b60008061152883610692565b909250905081156115e6576001600160a01b03808416600090815260116020908152604080832092909255600d5482517f0dfe168100000000000000000000000000000000000000000000000000000000815292516115e694889488949390911692630dfe168192600480840193829003018186803b1580156115aa57600080fd5b505afa1580156115be573d6000803e3d6000fd5b505050506040513d60208110156115d457600080fd5b50516001600160a01b03169190612afd565b8015611663576001600160a01b03808416600090815260136020908152604080832092909255600d5482517fd21220a700000000000000000000000000000000000000000000000000000000815292516116639488948794939091169263d21220a792600480840193829003018186803b1580156115aa57600080fd5b505050565b600080861161167657600080fd5b42841161168257600080fd5b8484111561168f57600080fd5b50600a80546001810190915560408051610100810182523381526001600160a01b0389166020820152908101879052606081018690526080810185905260a081016000815260208082018690526040918201859052600084815260158252829020835181546001600160a01b039182167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161783559285015160018084018054929093169190941617905591830151600280840191909155606084015160038401556080840151600484015560a0840151600584018054919390927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691849081111561179c57fe5b021790555060c0820151600682015560e090910151600790910155600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691630dfe1681916004808301926020929190829003018186803b15801561181557600080fd5b505afa158015611829573d6000803e3d6000fd5b505050506040513d602081101561183f57600080fd5b50516001600160a01b03898116911614156118d557600d60009054906101000a90046001600160a01b03166001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156118a257600080fd5b505afa1580156118b6573d6000803e3d6000fd5b505050506040513d60208110156118cc57600080fd5b505190506119fd565b600d60009054906101000a90046001600160a01b03166001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561192357600080fd5b505afa158015611937573d6000803e3d6000fd5b505050506040513d602081101561194d57600080fd5b50516001600160a01b03898116911614156119b057600d60009054906101000a90046001600160a01b03166001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156118a257600080fd5b6040805162461bcd60e51b815260206004820152600d60248201527f756e6b6e6f776e20746f6b656e00000000000000000000000000000000000000604482015290519081900360640190fd5b611a126001600160a01b03821633308a612bf4565b6040805183815290517f6f302d6e593bbaca357e385ecfa033d5b561c0141df25e8d931b308674fd8fad9181900360200190a1509695505050505050565b600f546001600160a01b031681565b600c54604080517f2f8d3a66000000000000000000000000000000000000000000000000000000008152306004820152905160009283926001600160a01b0390911691632f8d3a6691602480820192602092909190829003018186803b158015611ac857600080fd5b505afa158015611adc573d6000803e3d6000fd5b505050506040513d6020811015611af257600080fd5b5051905080611b05575050600554611b45565b611b4181611b2f670de0b6b3a7640000611b29600454611b29600954610776611b4e565b906127ff565b81611b3657fe5b60055491900461286b565b9150505b90565b60085481565b6000611b5c42600054612d05565b905090565b60008111611bb6576040805162461bcd60e51b815260206004820152601160248201527f63616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b611bc03382612a1d565b33600090815260146020526040902054611bda90826127a1565b33600081815260146020526040902091909155600d54611510916001600160a01b039091169083612afd565b60025481565b600b5481565b6001546001600160a01b031681565b60106020526000908152604090205481565b60075481565b600254611c4557600080fd5b600e54604080517ffa8e39b20000000000000000000000000000000000000000000000000000000081529051611ce8926001600160a01b03169163fa8e39b29160048083019260209291908290030181600087803b158015611ca657600080fd5b505af1158015611cba573d6000803e3d6000fd5b505050506040513d6020811015611cd057600080fd5b5051600254600d546001600160a01b03169190612afd565b6000600255565b60005481565b60035481565b600d546001600160a01b031681565b60095481565b60116020526000908152604090205481565b600e546001600160a01b031681565b600081815260156020526040812090600582015460ff166002811115611d5357fe5b14611d5d57600080fd5b6005810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660029081179091558154908201546001830154611db0926001600160a01b0391821692911690612afd565b6040805183815290517f0ff09947dd7d2583091e8cbfb427fecacb697bf895187b243fd0072c0ee9b9519181900360200190a15050565b600a5481565b600c54604080517f2f8d3a66000000000000000000000000000000000000000000000000000000008152306004820152905160009283926001600160a01b0390911691632f8d3a6691602480820192602092909190829003018186803b158015611e5657600080fd5b505afa158015611e6a573d6000803e3d6000fd5b505050506040513d6020811015611e8057600080fd5b5051905080611e93575050600854611b45565b611b4181611eb7670de0b6b3a7640000611b29600754611b29600954610776611b4e565b81611ebe57fe5b60085491900461286b565b600083815260156020526040812081600582015460ff166002811115611eeb57fe5b14611ef557600080fd5b42816004015411611f0557600080fd5b6005810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611f3a6132bf565b611f426132bf565b600d60009054906101000a90046001600160a01b03166001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611f9057600080fd5b505afa158015611fa4573d6000803e3d6000fd5b505050506040513d6020811015611fba57600080fd5b505160018401546001600160a01b0390811691161415612154576040805160608101825284546001600160a01b0390811682526002860154602080840191909152600d5484517f0dfe1681000000000000000000000000000000000000000000000000000000008152855194958601949190931692630dfe1681926004808301939192829003018186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d602081101561207b57600080fd5b50516001600160a01b039081169091526040805160608101825233815260208181018b9052600d5483517fd21220a70000000000000000000000000000000000000000000000000000000081528451969850929593860194169263d21220a7926004808201939291829003018186803b1580156120f757600080fd5b505afa15801561210b573d6000803e3d6000fd5b505050506040513d602081101561212157600080fd5b50516001600160a01b0390811690915281516020830151604084015193945061214f93909216913090612bf4565b6122cb565b604080516060810182523381526020808201899052600d5483517f0dfe1681000000000000000000000000000000000000000000000000000000008152845193948501936001600160a01b0390921692630dfe168192600480840193829003018186803b1580156121c457600080fd5b505afa1580156121d8573d6000803e3d6000fd5b505050506040513d60208110156121ee57600080fd5b50516001600160a01b03908116909152604080516060810182528654831681526002870154602082810191909152600d5483517fd21220a70000000000000000000000000000000000000000000000000000000081528451969850929593860194169263d21220a7926004808201939291829003018186803b15801561227357600080fd5b505afa158015612287573d6000803e3d6000fd5b505050506040513d602081101561229d57600080fd5b50516001600160a01b039081169091528351602085015160408601519394506122cb93909216913090612bf4565b60006103e861235a600e60009054906101000a90046001600160a01b03166001600160a01b0316638ace11306040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561232357600080fd5b505af1158015612337573d6000803e3d6000fd5b505050506040513d602081101561234d57600080fd5b50516020860151906127ff565b8161236157fe5b04905060006103e86123bc600e60009054906101000a90046001600160a01b03166001600160a01b0316638ace11306040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561232357600080fd5b816123c357fe5b0490506123dd8285602001516127a190919063ffffffff16565b6020808601919091528301516123f390826127a1565b602080850191909152600e54604080517ffa8e39b2000000000000000000000000000000000000000000000000000000008152905161249c936001600160a01b039093169263fa8e39b292600480820193918290030181600087803b15801561245b57600080fd5b505af115801561246f573d6000803e3d6000fd5b505050506040513d602081101561248557600080fd5b505160408601516001600160a01b03169084612afd565b600e54604080517ffa8e39b2000000000000000000000000000000000000000000000000000000008152905161253e926001600160a01b03169163fa8e39b29160048083019260209291908290030181600087803b1580156124fd57600080fd5b505af1158015612511573d6000803e3d6000fd5b505050506040513d602081101561252757600080fd5b505160408501516001600160a01b03169083612afd565b60408051600380825260808201909252600091829182916060919060208201838036833701905050905061258b888860405180604001604052808f81526020018d60060154815250612d1b565b90508060008151811061259a57fe5b60200260200101519150806001815181106125b157fe5b60200260200101519350806002815181106125c857fe5b602002602001015192506125ea8860000151600284816125e457fe5b04612b7d565b86516125f8906002846125e4565b60028206156126135760025461260f90600161286b565b6002555b600b549950600b6000815480929190600101919050555060405180610100016040528089600001516001600160a01b0316815260200185815260200188600001516001600160a01b031681526020018481526020018a6003015481526020018381526020016000151581526020018a60070154815250601660008c815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e082015181600701559050507f6991afcfa70e981e34df7ec69f37073cc382854b4bf5cd72b42a24cdcce4e7568d8b604051808381526020018281526020019250505060405180910390a15050505050505050505b9392505050565b60065481565b808203828111156127f9576040805162461bcd60e51b815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b92915050565b600081158061281a5750508082028282828161281757fe5b04145b6127f9576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b808201828110156127f9576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b8015806129625750604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561293457600080fd5b505afa158015612948573d6000803e3d6000fd5b505050506040513d602081101561295e57600080fd5b5051155b61299d5760405162461bcd60e51b81526004018080602001828103825260368152602001806133306036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052611663908490612fd3565b612a2682612c82565b600c54604080517f8600e40b0000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301526024820185905291519190921691638600e40b91604480830192600092919082900301818387803b158015612a9457600080fd5b505af1158015612aa8573d6000803e3d6000fd5b505050505050565b60008082841115612ae457612ac584846127a1565b905083612ad4826103e86127ff565b81612adb57fe5b049150506127f9565b612aee83856127a1565b905082612ad4826103e86127ff565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611663908490612fd3565b612b8682612c82565b600c54604080517fab53bddc0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018590529151919092169163ab53bddc91604480830192600092919082900301818387803b158015612a9457600080fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052612c7c908590612fd3565b50505050565b612c8a611a5f565b600555612c95611ded565b600855612ca0611b4e565b6009556001600160a01b0381161561151057600080612cbe83610692565b6001600160a01b0385166000908152601160209081526040808320949094556013815283822092909255600554601083528382205560085460129092529190912055505050565b6000818310612d145781612794565b5090919050565b600f546040840151606091612d3e916001600160a01b03908116911660006128c3565b600f546040840151612d5e916001600160a01b03918216911660006128c3565b600f5460208501516040860151612d83926001600160a01b03918216929116906128c3565b600f5460208401516040850151612da8926001600160a01b03918216929116906128c3565b6000612ddf6103e8612dcb856020015188602001516127ff90919063ffffffff16565b81612dd257fe5b60208801519190046127a1565b90506000612e046103e8612dcb866020015188602001516127ff90919063ffffffff16565b600f54604080890151888201516020808c0151908b01518a5185517fe8e337000000000000000000000000000000000000000000000000000000000081526001600160a01b0395861660048201529385166024850152604484019290925260648301526084820188905260a482018690523060c483015260e482015291519394506000938493849392169163e8e337009161010480830192606092919082900301818787803b158015612eb657600080fd5b505af1158015612eca573d6000803e3d6000fd5b505050506040513d6060811015612ee057600080fd5b508051602080830151604090930151908c0151919550919350909150831015612f2757885160208a015160408b0151612f27926001600160a01b0390911691869003612afd565b8760200151821015612f57578751602089015160408a0151612f57926001600160a01b0390911691859003612afd565b604080516003808252608082019092526060916020820183803683370190505090508181600081518110612f8757fe5b6020026020010181815250508381600181518110612fa157fe5b6020026020010181815250508281600281518110612fbb57fe5b60209081029190910101529998505050505050505050565b6060613028826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166130849092919063ffffffff16565b8051909150156116635780806020019051602081101561304757600080fd5b50516116635760405162461bcd60e51b815260040180806020018281038252602a815260200180613306602a913960400191505060405180910390fd5b6060613093848460008561309b565b949350505050565b6060824710156130dc5760405162461bcd60e51b81526004018080602001828103825260268152602001806132e06026913960400191505060405180910390fd5b6130e585613215565b613136576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061319357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613156565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146131f5576040519150601f19603f3d011682016040523d82523d6000602084013e6131fa565b606091505b509150915061320a82828661321b565b979650505050505050565b3b151590565b6060831561322a575081612794565b82511561323a5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561328457818101518382015260200161326c565b50505050905090810190601f1680156132b15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60408051606081018252600080825260208201819052918101919091529056fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c5361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220eb0de1f4cb77826c8c839bebed9978af31378c112175b0f4a128e173b625982364736f6c634300060c00334f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212203cd2088a29d59b0d2fc959462484018accc9c34777bea98d90284e609ccfcb5864736f6c634300060c0033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001725760003560e01c80638ace113011620000e1578063f2fde38b116200008d578063fa8e39b2116200006f578063fa8e39b214620003a4578063fafd267814620003ae578063fbef7eb714620003b85762000172565b8063f2fde38b146200033a578063f8c8765e14620003635762000172565b80638da5cb5b11620000c35780638da5cb5b14620002f0578063e16fc60b14620002fa578063e402aa1b146200031a5762000172565b80638ace113014620002dc5780638bdb2afa14620002e65762000172565b806343eabd241162000141578063715018a61162000123578063715018a614620002a8578063735de9f714620002b2578063753c7d5214620002bc5762000172565b806343eabd2414620002665780636103341d146200028c5762000172565b80630f4ef8a614620001775780632b261e85146200019d5780633be273a914620001bf57806340fbe74f146200023d575b600080fd5b6200018162000403565b604080516001600160a01b039092168252519081900360200190f35b620001bd60048036036020811015620001b557600080fd5b503562000412565b005b620001df60048036036020811015620001d757600080fd5b50356200069a565b60405180886001600160a01b03168152602001876001600160a01b031681526020018681526020018581526020018460038111156200021a57fe5b815260200183815260200182815260200197505050505050505060405180910390f35b620001bd600480360360208110156200025557600080fd5b50356001600160a01b0316620006e7565b62000181600480360360408110156200027e57600080fd5b508035906020013562000812565b6200029662000b6b565b60408051918252519081900360200190f35b620001bd62000b71565b6200018162000c40565b6200018160048036036020811015620002d457600080fd5b503562000c4f565b6200029662000c77565b6200018162000c7d565b6200018162000c8c565b620001bd600480360360208110156200031257600080fd5b503562000c9b565b62000296600480360360208110156200033257600080fd5b503562000d99565b620001bd600480360360208110156200035257600080fd5b50356001600160a01b031662000f4e565b620001bd600480360360808110156200037b57600080fd5b506001600160a01b03813581169160208101358216916040820135811691606001351662001076565b6200018162001190565b620001816200119f565b62000296600480360360c0811015620003d057600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a00135620011ae565b609d546001600160a01b031681565b6000818152609f6020526040902060018101546001600160a01b0316331462000482576040805162461bcd60e51b815260206004820152600a60248201527f217375626d697474657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000600482015460ff1660038111156200049857fe5b14620004eb576040805162461bcd60e51b815260206004820152600860248201527f2170656e64696e67000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60028101541562000520578054600182015460028301546001600160a01b03928316926200051e928492911690620014ad565b505b600581015415620005d957600181015460058201548254604080517f0dfe16810000000000000000000000000000000000000000000000000000000081529051620005d9946001600160a01b0390811694931691630dfe1681916004808301926020929190829003018186803b1580156200059a57600080fd5b505afa158015620005af573d6000803e3d6000fd5b505050506040513d6020811015620005c657600080fd5b50516001600160a01b03169190620014ad565b6006810154156200065357600181015460068201548254604080517fd21220a7000000000000000000000000000000000000000000000000000000008152905162000653946001600160a01b039081169493169163d21220a7916004808301926020929190829003018186803b1580156200059a57600080fd5b60048101805460ff191660021790556040805183815290517f3fe7c3ab7390584695c5228248ba66ebfb589b7d019e8dfcf410de8b58c6d3da916020908290030190a15050565b609f6020526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b039586169695909416949293919260ff9091169187565b620006f162001534565b6065546001600160a01b0390811691161462000754576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116620007b0576040805162461bcd60e51b815260206004820152600960248201527f2161646472657373300000000000000000000000000000000000000000000000604482015290519081900360640190fd5b609a80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f598c2941e1d126a56daa8263b130d6972c6914f8b3dbffe165eba3ee763ddb0b90600090a250565b60006200081e62001534565b6065546001600160a01b0390811691161462000881576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000838152609f6020526040812090600482015460ff166003811115620008a457fe5b14620008af57600080fd5b805460018201546003830154609854609d54600586015460068701546040516000976001600160a01b03908116978116969581169430949116929091620008f69062001d26565b6001600160a01b03988916815296881660208801526040808801969096529387166060870152918616608086015290941660a084015260c083019390935260e082019290925290519081900361010001906000f0801580156200095d573d6000803e3d6000fd5b50609d54604080517f2b8bbbe8000000000000000000000000000000000000000000000000000000008152600481018890526001600160a01b0380851660248301529151939650869450911691632b8bbbe89160448082019260009290919082900301818387803b158015620009d257600080fd5b505af1158015620009e7573d6000803e3d6000fd5b5050609980546001810182556000919091527f72a152ddfb8e864297c917af52ea6c1c68aead0fee1a62673fcc7e0c94979d000180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038781169190911790915560058501548554604080517f0dfe1681000000000000000000000000000000000000000000000000000000008152905162000ab8965089955092939190911691630dfe168191600480820192602092909190829003018186803b1580156200059a57600080fd5b62000b138383600601548460000160009054906101000a90046001600160a01b03166001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156200059a57600080fd5b600482018054600160ff199091161790556040805186815290516001600160a01b038516917f53dfc5dfee17ca6c290225be486789855a8181f7657a8136faa2ad53105858df919081900360200190a2505092915050565b609c5481565b62000b7b62001534565b6065546001600160a01b0390811691161462000bde576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6098546001600160a01b031681565b6099818154811062000c5d57fe5b6000918252602090912001546001600160a01b0316905081565b609b5490565b6097546001600160a01b031681565b6065546001600160a01b031690565b62000ca562001534565b6065546001600160a01b0390811691161462000d08576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000811162000d5e576040805162461bcd60e51b815260206004820152600360248201527f213c300000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b609b8190556040805182815290517f77ea96a8e905a231dc727a60298571c14e8380d3d55452178b3294ad914de7919181900360200190a150565b6000818152609f6020526040812060018101546001600160a01b0316331462000e09576040805162461bcd60e51b815260206004820152600a60248201527f217375626d697474657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600482015460ff16600381111562000e1f57fe5b1462000e72576040805162461bcd60e51b815260206004820152600960248201527f21617070726f7665640000000000000000000000000000000000000000000000604482015290519081900360640190fd5b806003015442101562000ecc576040805162461bcd60e51b815260206004820152600d60248201527f6e6f742079657420656e64656400000000000000000000000000000000000000604482015290519081900360640190fd5b60028101541562000f01578054600182015460028301546001600160a01b039283169262000eff928492911690620014ad565b505b60048101805460ff191660031790556040805184815290517fdeddae43b7a8a81e62d60690552663f8f21bbb7530e99d6e6dc9e9ed22419c5a916020908290030190a16002015492915050565b62000f5862001534565b6065546001600160a01b0390811691161462000fbb576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116620010025760405162461bcd60e51b81526004018080602001828103825260268152602001806200525d6026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600054610100900460ff16806200109257506200109262001538565b80620010a1575060005460ff16155b620010de5760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff161580156200110a576000805460ff1961ff0019909116610100171660011790555b620011146200153e565b609e80546001600160a01b038088167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556097805487841690831617905560988054868416908316179055609d805492851692909116919091179055801562001189576000805461ff00191690555b5050505050565b609a546001600160a01b031690565b609e546001600160a01b031681565b600042841162001205576040805162461bcd60e51b815260206004820152600860248201527f21646174656e6f77000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60975460009062001221906001600160a01b03168989620015fc565b90506001600160a01b0381166200127f576040805162461bcd60e51b815260206004820152600960248201527f2161646472657373300000000000000000000000000000000000000000000000604482015290519081900360640190fd5b85156200129d576200129d6001600160a01b038216333089620016e9565b8315620012bb57620012bb6001600160a01b038916333087620016e9565b8215620012d957620012d96001600160a01b038816333086620016e9565b806001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156200131357600080fd5b505afa15801562001328573d6000803e3d6000fd5b505050506040513d60208110156200133f57600080fd5b50516001600160a01b0389811691161462001358579192915b6040805160e0810182526001600160a01b0383811682523360208084019182528385018b8152606085018b815260006080870181815260a088018d905260c088018c9052609c805460018082019092558352609f909552979020865181549087167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216178255945181850180549190971695169490941790945551600283015591516003808301919091559351600482018054949592949193909260ff199092169184908111156200142857fe5b021790555060a0820151600582015560c090910151600690910155609c54604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909201808352905190917f1a5c43890324b09ae17af9bd2146b2ef30a3d51d30472357b87bc707e85f8d33919081900360200190a198975050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526200152f90849062001779565b505050565b3390565b303b1590565b600054610100900460ff16806200155a57506200155a62001538565b8062001569575060005460ff16155b620015a65760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff16158015620015d2576000805460ff1961ff0019909116610100171660011790555b620015dc62001830565b620015e6620018d8565b8015620015f9576000805461ff00191690555b50565b60008060006200160d8585620019f3565b604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526200177390859062001779565b50505050565b6060620017d0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662001ad69092919063ffffffff16565b8051909150156200152f57808060200190516020811015620017f157600080fd5b50516200152f5760405162461bcd60e51b815260040180806020018281038252602a815260200180620052fc602a913960400191505060405180910390fd5b600054610100900460ff16806200184c57506200184c62001538565b806200185b575060005460ff16155b620018985760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff16158015620015e6576000805460ff1961ff0019909116610100171660011790558015620015f9576000805461ff001916905550565b600054610100900460ff1680620018f45750620018f462001538565b8062001903575060005460ff16155b620019405760405162461bcd60e51b815260040180806020018281038252602e815260200180620052ce602e913960400191505060405180910390fd5b600054610100900460ff161580156200196c576000805460ff1961ff0019909116610100171660011790555b60006200197862001534565b606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015620015f9576000805461ff001916905550565b600080826001600160a01b0316846001600160a01b0316141562001a495760405162461bcd60e51b8152600401808060200182810382526025815260200180620052836025913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b03161062001a6b57828462001a6e565b83835b90925090506001600160a01b03821662001acf576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b9250929050565b606062001ae7848460008562001af1565b90505b9392505050565b60608247101562001b345760405162461bcd60e51b8152600401808060200182810382526026815260200180620052a86026913960400191505060405180910390fd5b62001b3f8562001c76565b62001b91576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831062001bf057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910162001bb1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811462001c54576040519150601f19603f3d011682016040523d82523d6000602084013e62001c59565b606091505b509150915062001c6b82828662001c7c565b979650505050505050565b3b151590565b6060831562001c8d57508162001aea565b82511562001c9e5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101562001cea57818101518382015260200162001cd0565b50505050905090810190601f16801562001d185780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6135288062001d358339019056fe60806040523480156200001157600080fd5b50604051620035283803806200352883398181016040526101008110156200003857600080fd5b50805160208083015160408401516060850151608086015160a087015160c088015160e090980151600e80546001600160a01b03199081166001600160a01b0380871691909117909255600d80548216838c161790556000878155600180548316848b16179055600f80548316848916179055600c8054909216928516929092179055979895979496939592949193909190620000e290889042906200011e811b620027a117901c565b60038490559050808381620000f357fe5b0460045560068290558082816200010657fe5b04600755505042600955506200017d95505050505050565b8082038281111562000177576040805162461bcd60e51b815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b92915050565b61339b806200018d6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638244bd1511610145578063c816841b116100bd578063ef706adf1161008c578063f8dd7c1011610071578063f8dd7c10146105d7578063fa42d8c2146105df578063fabc5a561461060857610241565b8063ef706adf146105b2578063f7e45bc7146105cf57610241565b8063c816841b14610574578063c8f33c911461057c578063e1550fde14610584578063e8f62764146105aa57610241565b80639fc26c3a11610114578063a25b6b0d116100f9578063a25b6b0d1461055c578063c24a0f8b14610564578063c6dbfb8a1461056c57610241565b80639fc26c3a1461052e578063a08363ea1461055457610241565b80638244bd15146104f957806383d490291461051657806387dcec951461051e5780638dc45d9a1461052657610241565b806336e707e8116101d85780636d4af7e9116101a757806377322c371161018c57806377322c37146104e15780637eea237a146104e957806380faa57d146104f157610241565b80636d4af7e914610495578063735de9f7146104d957610241565b806336e707e8146103ab5780633903cc72146103d157806341655ee51461045257806364b3e1531461046f57610241565b806310facdd01161021457806310facdd0146102fb57806316ba6bf314610321578063202e909f14610360578063366a41201461038657610241565b806303a28f4c146102465780630e518506146102605780630eaf1036146102cf5780630f4ef8a6146102d7575b600080fd5b61024e610610565b60408051918252519081900360200190f35b61027d6004803603602081101561027657600080fd5b5035610616565b604080516001600160a01b03998a168152602081019890985295909716868601526060860193909352608085019190915260a0840152151560c083015260e08201929092529051908190036101000190f35b61024e61066b565b6102df610671565b604080516001600160a01b039092168252519081900360200190f35b61024e6004803603602081101561031157600080fd5b50356001600160a01b0316610680565b6103476004803603602081101561033757600080fd5b50356001600160a01b0316610692565b6040805192835260208301919091528051918290030190f35b61024e6004803603602081101561037657600080fd5b50356001600160a01b03166107df565b6103a96004803603604081101561039c57600080fd5b50803590602001356107f1565b005b61024e600480360360208110156103c157600080fd5b50356001600160a01b0316611404565b6103ee600480360360208110156103e757600080fd5b5035611416565b60405180896001600160a01b03168152602001886001600160a01b0316815260200187815260200186815260200185815260200184600281111561042e57fe5b81526020018381526020018281526020019850505050505050505060405180910390f35b6103a96004803603602081101561046857600080fd5b503561146a565b6103a96004803603602081101561048557600080fd5b50356001600160a01b0316611513565b61024e600480360360c08110156104ab57600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a00135611668565b6102df611a50565b61024e611a5f565b61024e611b48565b61024e611b4e565b6103a96004803603602081101561050f57600080fd5b5035611b61565b61024e611c06565b61024e611c0c565b6102df611c12565b61024e6004803603602081101561054457600080fd5b50356001600160a01b0316611c21565b61024e611c33565b6103a9611c39565b61024e611cef565b61024e611cf5565b6102df611cfb565b61024e611d0a565b61024e6004803603602081101561059a57600080fd5b50356001600160a01b0316611d10565b6102df611d22565b6103a9600480360360208110156105c857600080fd5b5035611d31565b61024e611de7565b61024e611ded565b61024e600480360360608110156105f557600080fd5b5080359060208101359060400135611ec9565b61024e61279b565b60055481565b601660205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b039687169795969094169492939192909160ff9091169088565b60045481565b600c546001600160a01b031681565b60136020526000908152604090205481565b600c54604080517f9f1916590000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038481166024830152915160009384938493911691639f19165991604480820192602092909190829003018186803b15801561070457600080fd5b505afa158015610718573d6000803e3d6000fd5b505050506040513d602081101561072e57600080fd5b50516001600160a01b03851660009081526011602090815260408083205460109092529091205491925061079191670de0b6b3a7640000906107839061077c90610776611a5f565b906127a1565b85906127ff565b8161078a57fe5b049061286b565b6001600160a01b0385166000908152601360209081526040808320546012909252909120549194506107d791670de0b6b3a7640000906107839061077c90610776611ded565b915050915091565b60126020526000908152604090205481565b600082815260166020526040902080546001600160a01b0316331480610823575060028101546001600160a01b031633145b610874576040805162461bcd60e51b815260206004820152600c60248201527f756e617574686f72697a65640000000000000000000000000000000000000000604482015290519081900360640190fd5b806004015442116108cc576040805162461bcd60e51b815260206004820152600660248201527f6c6f636b65640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600681015460ff1615610926576040805162461bcd60e51b815260206004820152601060248201527f616c72656164792072656c656173656400000000000000000000000000000000604482015290519081900360640190fd5b6006810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691630dfe1681916004808301926020929190829003018186803b1580156109b157600080fd5b505afa1580156109c5573d6000803e3d6000fd5b505050506040513d60208110156109db57600080fd5b5051600d54604080517fd21220a700000000000000000000000000000000000000000000000000000000815290519293506000926001600160a01b039092169163d21220a791600480820192602092909190829003018186803b158015610a4157600080fd5b505afa158015610a55573d6000803e3d6000fd5b505050506040513d6020811015610a6b57600080fd5b5051600f54600d54919250610a8e916001600160a01b03908116911660006128c3565b600f546005840154600d54610ab1926001600160a01b03918216929116906128c3565b600f546005840154604080517fbaa2abde0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015285811660248301526044820193909352600060648201819052608482018190523060a483015260c48201899052825190948594169263baa2abde9260e4808201939182900301818787803b158015610b4757600080fd5b505af1158015610b5b573d6000803e3d6000fd5b505050506040513d6040811015610b7157600080fd5b50805160209091015186546005880154929450909250610ba1916001600160a01b03909116906002905b04612a1d565b6002808601546005870154610bc2926001600160a01b039092169190610b9b565b8460070154610bd5866001015484612ab0565b1115610f95578460010154821115610f95576000610c008660010154846127a190919063ffffffff16565b6040805160028082526060808301845293945090916020830190803683375050600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290519394506001600160a01b0390911692630dfe168192506004808301926020929190829003018186803b158015610c8157600080fd5b505afa158015610c95573d6000803e3d6000fd5b505050506040513d6020811015610cab57600080fd5b505181518290600090610cba57fe5b6001600160a01b03928316602091820292909201810191909152600d54604080517fd21220a70000000000000000000000000000000000000000000000000000000081529051919093169263d21220a7926004808301939192829003018186803b158015610d2757600080fd5b505afa158015610d3b573d6000803e3d6000fd5b505050506040513d6020811015610d5157600080fd5b5051815182906001908110610d6257fe5b6001600160a01b039283166020918202929092010152600f54610d8b91888116911660006128c3565b600f54610da5906001600160a01b038881169116846128c3565b6060600f60009054906101000a90046001600160a01b03166001600160a01b03166338ed173984600085308e6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015610e41578181015183820152602001610e29565b505050509050019650505050505050600060405180830381600087803b158015610e6a57600080fd5b505af1158015610e7e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015610ec557600080fd5b8101908080516040519392919084640100000000821115610ee557600080fd5b908301906020820185811115610efa57600080fd5b8251866020820283011164010000000082111715610f1757600080fd5b82525081516020918201928201910280838360005b83811015610f44578181015183820152602001610f2c565b505050509050016040525050509050610f6683866127a190919063ffffffff16565b9450610f8f81600181518110610f7857fe5b60200260200101518561286b90919063ffffffff16565b93505050505b8460070154610fa8866003015483612ab0565b1115611368578460030154811115611368576000610fd38660030154836127a190919063ffffffff16565b6040805160028082526060808301845293945090916020830190803683375050600d54604080517fd21220a700000000000000000000000000000000000000000000000000000000815290519394506001600160a01b039091169263d21220a792506004808301926020929190829003018186803b15801561105457600080fd5b505afa158015611068573d6000803e3d6000fd5b505050506040513d602081101561107e57600080fd5b50518151829060009061108d57fe5b6001600160a01b03928316602091820292909201810191909152600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290519190931692630dfe1681926004808301939192829003018186803b1580156110fa57600080fd5b505afa15801561110e573d6000803e3d6000fd5b505050506040513d602081101561112457600080fd5b505181518290600190811061113557fe5b6001600160a01b039283166020918202929092010152600f5461115e91878116911660006128c3565b600f54611178906001600160a01b038781169116846128c3565b6060600f60009054906101000a90046001600160a01b03166001600160a01b03166338ed173984600085308e6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b838110156112145781810151838201526020016111fc565b505050509050019650505050505050600060405180830381600087803b15801561123d57600080fd5b505af1158015611251573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561129857600080fd5b81019080805160405193929190846401000000008211156112b857600080fd5b9083019060208201858111156112cd57600080fd5b82518660208202830111640100000000821117156112ea57600080fd5b82525081516020918201928201910280838360005b838110156113175781810151838201526020016112ff565b50505050905001604052505050905061133983856127a190919063ffffffff16565b93506113628160018151811061134b57fe5b60200260200101518661286b90919063ffffffff16565b94505050505b8454611381906001600160a01b03868116911684612afd565b8454611395906001600160a01b0316611513565b60028501546113b1906001600160a01b03858116911683612afd565b60028501546113c8906001600160a01b0316611513565b6040805188815290517f59a55455fb2332116ca78fe864f670ef66bae65460339946369d37fc255cbdb89181900360200190a150505050505050565b60146020526000908152604090205481565b601560205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b0396871697959096169593949293919260ff9091169188565b600081116114bf576040805162461bcd60e51b815260206004820152600e60248201527f63616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b6114c93382612b7d565b336000908152601460205260409020546114e3908261286b565b33600081815260146020526040902091909155600d54611510916001600160a01b03909116903084612bf4565b50565b61151c81612c82565b60008061152883610692565b909250905081156115e6576001600160a01b03808416600090815260116020908152604080832092909255600d5482517f0dfe168100000000000000000000000000000000000000000000000000000000815292516115e694889488949390911692630dfe168192600480840193829003018186803b1580156115aa57600080fd5b505afa1580156115be573d6000803e3d6000fd5b505050506040513d60208110156115d457600080fd5b50516001600160a01b03169190612afd565b8015611663576001600160a01b03808416600090815260136020908152604080832092909255600d5482517fd21220a700000000000000000000000000000000000000000000000000000000815292516116639488948794939091169263d21220a792600480840193829003018186803b1580156115aa57600080fd5b505050565b600080861161167657600080fd5b42841161168257600080fd5b8484111561168f57600080fd5b50600a80546001810190915560408051610100810182523381526001600160a01b0389166020820152908101879052606081018690526080810185905260a081016000815260208082018690526040918201859052600084815260158252829020835181546001600160a01b039182167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161783559285015160018084018054929093169190941617905591830151600280840191909155606084015160038401556080840151600484015560a0840151600584018054919390927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691849081111561179c57fe5b021790555060c0820151600682015560e090910151600790910155600d54604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691630dfe1681916004808301926020929190829003018186803b15801561181557600080fd5b505afa158015611829573d6000803e3d6000fd5b505050506040513d602081101561183f57600080fd5b50516001600160a01b03898116911614156118d557600d60009054906101000a90046001600160a01b03166001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156118a257600080fd5b505afa1580156118b6573d6000803e3d6000fd5b505050506040513d60208110156118cc57600080fd5b505190506119fd565b600d60009054906101000a90046001600160a01b03166001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561192357600080fd5b505afa158015611937573d6000803e3d6000fd5b505050506040513d602081101561194d57600080fd5b50516001600160a01b03898116911614156119b057600d60009054906101000a90046001600160a01b03166001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156118a257600080fd5b6040805162461bcd60e51b815260206004820152600d60248201527f756e6b6e6f776e20746f6b656e00000000000000000000000000000000000000604482015290519081900360640190fd5b611a126001600160a01b03821633308a612bf4565b6040805183815290517f6f302d6e593bbaca357e385ecfa033d5b561c0141df25e8d931b308674fd8fad9181900360200190a1509695505050505050565b600f546001600160a01b031681565b600c54604080517f2f8d3a66000000000000000000000000000000000000000000000000000000008152306004820152905160009283926001600160a01b0390911691632f8d3a6691602480820192602092909190829003018186803b158015611ac857600080fd5b505afa158015611adc573d6000803e3d6000fd5b505050506040513d6020811015611af257600080fd5b5051905080611b05575050600554611b45565b611b4181611b2f670de0b6b3a7640000611b29600454611b29600954610776611b4e565b906127ff565b81611b3657fe5b60055491900461286b565b9150505b90565b60085481565b6000611b5c42600054612d05565b905090565b60008111611bb6576040805162461bcd60e51b815260206004820152601160248201527f63616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b611bc03382612a1d565b33600090815260146020526040902054611bda90826127a1565b33600081815260146020526040902091909155600d54611510916001600160a01b039091169083612afd565b60025481565b600b5481565b6001546001600160a01b031681565b60106020526000908152604090205481565b60075481565b600254611c4557600080fd5b600e54604080517ffa8e39b20000000000000000000000000000000000000000000000000000000081529051611ce8926001600160a01b03169163fa8e39b29160048083019260209291908290030181600087803b158015611ca657600080fd5b505af1158015611cba573d6000803e3d6000fd5b505050506040513d6020811015611cd057600080fd5b5051600254600d546001600160a01b03169190612afd565b6000600255565b60005481565b60035481565b600d546001600160a01b031681565b60095481565b60116020526000908152604090205481565b600e546001600160a01b031681565b600081815260156020526040812090600582015460ff166002811115611d5357fe5b14611d5d57600080fd5b6005810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660029081179091558154908201546001830154611db0926001600160a01b0391821692911690612afd565b6040805183815290517f0ff09947dd7d2583091e8cbfb427fecacb697bf895187b243fd0072c0ee9b9519181900360200190a15050565b600a5481565b600c54604080517f2f8d3a66000000000000000000000000000000000000000000000000000000008152306004820152905160009283926001600160a01b0390911691632f8d3a6691602480820192602092909190829003018186803b158015611e5657600080fd5b505afa158015611e6a573d6000803e3d6000fd5b505050506040513d6020811015611e8057600080fd5b5051905080611e93575050600854611b45565b611b4181611eb7670de0b6b3a7640000611b29600754611b29600954610776611b4e565b81611ebe57fe5b60085491900461286b565b600083815260156020526040812081600582015460ff166002811115611eeb57fe5b14611ef557600080fd5b42816004015411611f0557600080fd5b6005810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611f3a6132bf565b611f426132bf565b600d60009054906101000a90046001600160a01b03166001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611f9057600080fd5b505afa158015611fa4573d6000803e3d6000fd5b505050506040513d6020811015611fba57600080fd5b505160018401546001600160a01b0390811691161415612154576040805160608101825284546001600160a01b0390811682526002860154602080840191909152600d5484517f0dfe1681000000000000000000000000000000000000000000000000000000008152855194958601949190931692630dfe1681926004808301939192829003018186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d602081101561207b57600080fd5b50516001600160a01b039081169091526040805160608101825233815260208181018b9052600d5483517fd21220a70000000000000000000000000000000000000000000000000000000081528451969850929593860194169263d21220a7926004808201939291829003018186803b1580156120f757600080fd5b505afa15801561210b573d6000803e3d6000fd5b505050506040513d602081101561212157600080fd5b50516001600160a01b0390811690915281516020830151604084015193945061214f93909216913090612bf4565b6122cb565b604080516060810182523381526020808201899052600d5483517f0dfe1681000000000000000000000000000000000000000000000000000000008152845193948501936001600160a01b0390921692630dfe168192600480840193829003018186803b1580156121c457600080fd5b505afa1580156121d8573d6000803e3d6000fd5b505050506040513d60208110156121ee57600080fd5b50516001600160a01b03908116909152604080516060810182528654831681526002870154602082810191909152600d5483517fd21220a70000000000000000000000000000000000000000000000000000000081528451969850929593860194169263d21220a7926004808201939291829003018186803b15801561227357600080fd5b505afa158015612287573d6000803e3d6000fd5b505050506040513d602081101561229d57600080fd5b50516001600160a01b039081169091528351602085015160408601519394506122cb93909216913090612bf4565b60006103e861235a600e60009054906101000a90046001600160a01b03166001600160a01b0316638ace11306040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561232357600080fd5b505af1158015612337573d6000803e3d6000fd5b505050506040513d602081101561234d57600080fd5b50516020860151906127ff565b8161236157fe5b04905060006103e86123bc600e60009054906101000a90046001600160a01b03166001600160a01b0316638ace11306040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561232357600080fd5b816123c357fe5b0490506123dd8285602001516127a190919063ffffffff16565b6020808601919091528301516123f390826127a1565b602080850191909152600e54604080517ffa8e39b2000000000000000000000000000000000000000000000000000000008152905161249c936001600160a01b039093169263fa8e39b292600480820193918290030181600087803b15801561245b57600080fd5b505af115801561246f573d6000803e3d6000fd5b505050506040513d602081101561248557600080fd5b505160408601516001600160a01b03169084612afd565b600e54604080517ffa8e39b2000000000000000000000000000000000000000000000000000000008152905161253e926001600160a01b03169163fa8e39b29160048083019260209291908290030181600087803b1580156124fd57600080fd5b505af1158015612511573d6000803e3d6000fd5b505050506040513d602081101561252757600080fd5b505160408501516001600160a01b03169083612afd565b60408051600380825260808201909252600091829182916060919060208201838036833701905050905061258b888860405180604001604052808f81526020018d60060154815250612d1b565b90508060008151811061259a57fe5b60200260200101519150806001815181106125b157fe5b60200260200101519350806002815181106125c857fe5b602002602001015192506125ea8860000151600284816125e457fe5b04612b7d565b86516125f8906002846125e4565b60028206156126135760025461260f90600161286b565b6002555b600b549950600b6000815480929190600101919050555060405180610100016040528089600001516001600160a01b0316815260200185815260200188600001516001600160a01b031681526020018481526020018a6003015481526020018381526020016000151581526020018a60070154815250601660008c815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e082015181600701559050507f6991afcfa70e981e34df7ec69f37073cc382854b4bf5cd72b42a24cdcce4e7568d8b604051808381526020018281526020019250505060405180910390a15050505050505050505b9392505050565b60065481565b808203828111156127f9576040805162461bcd60e51b815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b92915050565b600081158061281a5750508082028282828161281757fe5b04145b6127f9576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b808201828110156127f9576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b8015806129625750604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561293457600080fd5b505afa158015612948573d6000803e3d6000fd5b505050506040513d602081101561295e57600080fd5b5051155b61299d5760405162461bcd60e51b81526004018080602001828103825260368152602001806133306036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052611663908490612fd3565b612a2682612c82565b600c54604080517f8600e40b0000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301526024820185905291519190921691638600e40b91604480830192600092919082900301818387803b158015612a9457600080fd5b505af1158015612aa8573d6000803e3d6000fd5b505050505050565b60008082841115612ae457612ac584846127a1565b905083612ad4826103e86127ff565b81612adb57fe5b049150506127f9565b612aee83856127a1565b905082612ad4826103e86127ff565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611663908490612fd3565b612b8682612c82565b600c54604080517fab53bddc0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018590529151919092169163ab53bddc91604480830192600092919082900301818387803b158015612a9457600080fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052612c7c908590612fd3565b50505050565b612c8a611a5f565b600555612c95611ded565b600855612ca0611b4e565b6009556001600160a01b0381161561151057600080612cbe83610692565b6001600160a01b0385166000908152601160209081526040808320949094556013815283822092909255600554601083528382205560085460129092529190912055505050565b6000818310612d145781612794565b5090919050565b600f546040840151606091612d3e916001600160a01b03908116911660006128c3565b600f546040840151612d5e916001600160a01b03918216911660006128c3565b600f5460208501516040860151612d83926001600160a01b03918216929116906128c3565b600f5460208401516040850151612da8926001600160a01b03918216929116906128c3565b6000612ddf6103e8612dcb856020015188602001516127ff90919063ffffffff16565b81612dd257fe5b60208801519190046127a1565b90506000612e046103e8612dcb866020015188602001516127ff90919063ffffffff16565b600f54604080890151888201516020808c0151908b01518a5185517fe8e337000000000000000000000000000000000000000000000000000000000081526001600160a01b0395861660048201529385166024850152604484019290925260648301526084820188905260a482018690523060c483015260e482015291519394506000938493849392169163e8e337009161010480830192606092919082900301818787803b158015612eb657600080fd5b505af1158015612eca573d6000803e3d6000fd5b505050506040513d6060811015612ee057600080fd5b508051602080830151604090930151908c0151919550919350909150831015612f2757885160208a015160408b0151612f27926001600160a01b0390911691869003612afd565b8760200151821015612f57578751602089015160408a0151612f57926001600160a01b0390911691859003612afd565b604080516003808252608082019092526060916020820183803683370190505090508181600081518110612f8757fe5b6020026020010181815250508381600181518110612fa157fe5b6020026020010181815250508281600281518110612fbb57fe5b60209081029190910101529998505050505050505050565b6060613028826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166130849092919063ffffffff16565b8051909150156116635780806020019051602081101561304757600080fd5b50516116635760405162461bcd60e51b815260040180806020018281038252602a815260200180613306602a913960400191505060405180910390fd5b6060613093848460008561309b565b949350505050565b6060824710156130dc5760405162461bcd60e51b81526004018080602001828103825260268152602001806132e06026913960400191505060405180910390fd5b6130e585613215565b613136576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061319357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613156565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146131f5576040519150601f19603f3d011682016040523d82523d6000602084013e6131fa565b606091505b509150915061320a82828661321b565b979650505050505050565b3b151590565b6060831561322a575081612794565b82511561323a5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561328457818101518382015260200161326c565b50505050905090810190601f1680156132b15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60408051606081018252600080825260208201819052918101919091529056fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c5361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220eb0de1f4cb77826c8c839bebed9978af31378c112175b0f4a128e173b625982364736f6c634300060c00334f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212203cd2088a29d59b0d2fc959462484018accc9c34777bea98d90284e609ccfcb5864736f6c634300060c0033
Deployed Bytecode Sourcemap
53263:6215:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53610:35;;;:::i;:::-;;;;-1:-1:-1;;;;;53610:35:0;;;;;;;;;;;;;;57251:932;;;;;;;;;;;;;;;;-1:-1:-1;57251:932:0;;:::i;:::-;;53691:44;;;;;;;;;;;;;;;;-1:-1:-1;53691:44:0;;:::i;:::-;;;;;-1:-1:-1;;;;;53691:44:0;;;;;;-1:-1:-1;;;;;53691:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58191:201;;;;;;;;;;;;;;;;-1:-1:-1;58191:201:0;-1:-1:-1;;;;;58191:201:0;;:::i;56174:1069::-;;;;;;;;;;;;;;;;-1:-1:-1;56174:1069:0;;;;;;;:::i;53573:30::-;;;:::i;:::-;;;;;;;;;;;;;;;;5376:148;;;:::i;53434:28::-;;;:::i;53469:23::-;;;;;;;;;;;;;;;;-1:-1:-1;53469:23:0;;:::i;58493:87::-;;;:::i;53398:29::-;;;:::i;4734:79::-;;;:::i;58588:192::-;;;;;;;;;;;;;;;;-1:-1:-1;58588:192:0;;:::i;58788:687::-;;;;;;;;;;;;;;;;-1:-1:-1;58788:687:0;;:::i;5679:244::-;;;;;;;;;;;;;;;;-1:-1:-1;5679:244:0;-1:-1:-1;;;;;5679:244:0;;:::i;54286:416::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54286:416:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;58400:85::-;;;:::i;53652:30::-;;;:::i;54710:1456::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54710:1456:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;53610:35::-;;;-1:-1:-1;;;;;53610:35:0;;:::o;57251:932::-;57313:29;57345:14;;;:6;:14;;;;;57380:20;;;;-1:-1:-1;;;;;57380:20:0;57404:10;57380:34;57372:57;;;;;-1:-1:-1;;;57372:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57469:17;57448;;;;;;:38;;;;;;;;;57440:59;;;;;-1:-1:-1;;;57440:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57516:20;;;;:24;57512:210;;57594:22;;;57667:20;;;57689;;;;-1:-1:-1;;;;;57594:22:0;;;;57632:78;;57594:22;;57667:20;;;57632:34;:78::i;:::-;57512:210;;57738:22;;;;:26;57734:173;;57850:20;;;;57872:22;;;;57803;;57788:47;;;;;;;;57781:114;;-1:-1:-1;;;;;57850:20:0;;;;57872:22;57803;;57788:45;;:47;;;;;;;;;;;;;;57803:22;57788:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57788:47:0;-1:-1:-1;;;;;57781:68:0;;:114;:68;:114::i;:::-;57921:22;;;;:26;57917:173;;58033:20;;;;58055:22;;;;57986;;57971:47;;;;;;;;57964:114;;-1:-1:-1;;;;;58033:20:0;;;;58055:22;57986;;57971:45;;:47;;;;;;;;;;;;;;57986:22;57971:47;;;;;;;;;;57964:114;58102:17;;;:38;;-1:-1:-1;;58102:38:0;58122:18;58102:38;;;58156:19;;;;;;;;;;;;;;;;;;57251:932;;:::o;53691:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53691:44:0;;;;;;;;;;;;;;;;;;;:::o;58191:201::-;4956:12;:10;:12::i;:::-;4946:6;;-1:-1:-1;;;;;4946:6:0;;;:22;;;4938:67;;;;;-1:-1:-1;;;4938:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58275:24:0;::::1;58267:46;;;::::0;;-1:-1:-1;;;58267:46:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;58324:7;:20:::0;;;::::1;-1:-1:-1::0;;;;;58324:20:0;::::1;::::0;;::::1;::::0;;;58360:24:::1;::::0;::::1;::::0;-1:-1:-1;;58360:24:0::1;58191:201:::0;:::o;56174:1069::-;56261:18;4956:12;:10;:12::i;:::-;4946:6;;-1:-1:-1;;;;;4946:6:0;;;:22;;;4938:67;;;;;-1:-1:-1;;;4938:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56292:29:::1;56324:14:::0;;;:6:::1;:14;::::0;;;;;56357:17:::1;::::0;::::1;::::0;::::1;;:38;::::0;::::1;;;;;;;56349:47;;;::::0;::::1;;56461:22:::0;;;56502:20;::::1;::::0;56541:18:::1;::::0;::::1;::::0;56578:13:::1;::::0;56642::::1;::::0;56674:22:::1;::::0;::::1;::::0;56715::::1;::::0;::::1;::::0;56435:317:::1;::::0;56409:10:::1;::::0;-1:-1:-1;;;;;56461:22:0;;::::1;::::0;56502:20;::::1;::::0;56541:18;56578:13;::::1;::::0;56618:4:::1;::::0;56642:13;::::1;::::0;56674:22;;56435:317:::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;;56435:317:0;;::::1;::::0;;;;::::1;;::::0;::::1;::::0;;;;;;;;;;;::::1;::::0;;;;;;::::1;::::0;;;;;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56435:317:0::1;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;56802:13:0::1;::::0;:42:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;-1:-1:-1;;;;;56802:42:0;;::::1;::::0;;;;;;56409:343;;-1:-1:-1;56409:343:0;;-1:-1:-1;56802:13:0;::::1;::::0;:17:::1;::::0;:42;;;;;:13:::1;::::0;:42;;;;;;;;:13;;:42;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;56855:6:0::1;:23:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;56855:23:0;;;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;;56855:23:0;;::::1;::::0;;;::::1;::::0;;;56970:22:::1;::::0;::::1;::::0;56911;;56896:47:::1;::::0;;;;;;;56889:104:::1;::::0;-1:-1:-1;56855:23:0;;-1:-1:-1;56970:22:0;;56911;;;::::1;::::0;56896:45:::1;::::0;:47:::1;::::0;;::::1;::::0;56855:23:::1;::::0;56896:47;;;;;;;;56911:22;56896:47;::::1;;::::0;::::1;;;;::::0;::::1;56889:104;57004;57073:10;57085;:22;;;57026:10;:22;;;;;;;;;;-1:-1:-1::0;;;;;57026:22:0::1;-1:-1:-1::0;;;;;57011:45:0::1;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;57004:104;57121:17;::::0;::::1;:38:::0;;57141:18:::1;-1:-1:-1::0;;57121:38:0;;::::1;;::::0;;57175:30:::1;::::0;;;;;;;-1:-1:-1;;;;;57175:30:0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;57218:17;;56174:1069:::0;;;;:::o;53573:30::-;;;;:::o;5376:148::-;4956:12;:10;:12::i;:::-;4946:6;;-1:-1:-1;;;;;4946:6:0;;;:22;;;4938:67;;;;;-1:-1:-1;;;4938:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5467:6:::1;::::0;5446:40:::1;::::0;5483:1:::1;::::0;-1:-1:-1;;;;;5467:6:0::1;::::0;5446:40:::1;::::0;5483:1;;5446:40:::1;5497:6;:19:::0;;;::::1;::::0;;5376:148::o;53434:28::-;;;-1:-1:-1;;;;;53434:28:0;;:::o;53469:23::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53469:23:0;;-1:-1:-1;53469:23:0;:::o;58493:87::-;58564:8;;58493:87;:::o;53398:29::-;;;-1:-1:-1;;;;;53398:29:0;;:::o;4734:79::-;4799:6;;-1:-1:-1;;;;;4799:6:0;4734:79;:::o;58588:192::-;4956:12;:10;:12::i;:::-;4946:6;;-1:-1:-1;;;;;4946:6:0;;;:22;;;4938:67;;;;;-1:-1:-1;;;4938:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58688:1:::1;58674:11;:15;58666:31;;;::::0;;-1:-1:-1;;;58666:31:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;58708:8;:22:::0;;;58746:26:::1;::::0;;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;58588:192:::0;:::o;58788:687::-;58845:7;58897:14;;;:6;:14;;;;;58932:20;;;;-1:-1:-1;;;;;58932:20:0;58956:10;58932:34;58924:57;;;;;-1:-1:-1;;;58924:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59021:18;59000:17;;;;;;:39;;;;;;;;;58992:61;;;;;-1:-1:-1;;;58992:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59091:10;:18;;;59072:15;:37;;59064:63;;;;;-1:-1:-1;;;59064:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59144:20;;;;:24;59140:210;;59222:22;;;59295:20;;;59317;;;;-1:-1:-1;;;;;59222:22:0;;;;59260:78;;59222:22;;59295:20;;;59260:34;:78::i;:::-;59140:210;;59362:17;;;:35;;-1:-1:-1;;59362:35:0;59382:15;59362:35;;;59413:16;;;;;;;;;;;;;;;;;;59447:20;;;;58788:687;-1:-1:-1;;58788:687:0:o;5679:244::-;4956:12;:10;:12::i;:::-;4946:6;;-1:-1:-1;;;;;4946:6:0;;;:22;;;4938:67;;;;;-1:-1:-1;;;4938:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5768:22:0;::::1;5760:73;;;;-1:-1:-1::0;;;5760:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5870:6;::::0;5849:38:::1;::::0;-1:-1:-1;;;;;5849:38:0;;::::1;::::0;5870:6:::1;::::0;5849:38:::1;::::0;5870:6:::1;::::0;5849:38:::1;5898:6;:17:::0;;;::::1;-1:-1:-1::0;;;;;5898:17:0;;;::::1;::::0;;;::::1;::::0;;5679:244::o;54286:416::-;1106:12;;;;;;;;:31;;;1122:15;:13;:15::i;:::-;1106:47;;;-1:-1:-1;1142:11:0;;;;1141:12;1106:47;1098:106;;;;-1:-1:-1;;;1098:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1217:19;1240:12;;;;;;1239:13;1263:99;;;;1298:12;:19;;-1:-1:-1;;;;1298:19:0;;;;;1332:18;1313:4;1332:18;;;1263:99;54471:35:::1;:33;:35::i;:::-;54517:8;:36:::0;;-1:-1:-1;;;;;54517:36:0;;::::1;::::0;;;::::1;;::::0;;;54564:14:::1;:32:::0;;;;::::1;::::0;;::::1;;::::0;;54607:13:::1;:30:::0;;;;::::1;::::0;;::::1;;::::0;;54648:13:::1;:46:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;1388:67;;;;1438:5;1423:20;;-1:-1:-1;;1423:20:0;;;1388:67;54286:416;;;;;:::o;58400:85::-;58470:7;;-1:-1:-1;;;;;58470:7:0;58400:85;:::o;53652:30::-;;;-1:-1:-1;;;;;53652:30:0;;:::o;54710:1456::-;54931:7;54970:3;54959:8;:14;54951:35;;;;;-1:-1:-1;;;54951:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55061:14;;54999:19;;55036:58;;-1:-1:-1;;;;;55061:14:0;55077:7;55086;55036:24;:58::i;:::-;54999:96;-1:-1:-1;;;;;;55114:27:0;;55106:49;;;;;-1:-1:-1;;;55106:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55172:14;;55168:124;;55203:77;-1:-1:-1;;;;;55203:38:0;;55242:10;55262:4;55269:10;55203:38;:77::i;:::-;55306:16;;55302:122;;55339:73;-1:-1:-1;;;;;55339:32:0;;55372:10;55392:4;55399:12;55339:32;:73::i;:::-;55438:16;;55434:122;;55471:73;-1:-1:-1;;;;;55471:32:0;;55504:10;55524:4;55531:12;55471:32;:73::i;:::-;55583:4;-1:-1:-1;;;;;55583:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55583:13:0;-1:-1:-1;;;;;55572:24:0;;;;;;55568:158;;55669:12;;55627;55568:158;55766:288;;;;;;;;-1:-1:-1;;;;;55766:288:0;;;;;55844:10;55766:288;;;;;;;;;;;;;;;;;;;-1:-1:-1;55766:288:0;;;;;;;;;;;;;;;;;;55745:15;:17;;;;;;;;;55738:25;;:6;:25;;;;;;:316;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55766:288;;55738:25;;:316;;;;-1:-1:-1;;55738:316:0;;;;;;;;;;;;;;;;;-1:-1:-1;55738:316:0;;;;;;;;;;;;;;;;;;56081:15;;56116:19;;;-1:-1:-1;56081:19:0;;;;56116;;;;;56081;;56116;;;;;;;;;;56153:5;54710:1456;-1:-1:-1;;;;;;;;54710:1456:0:o;32041:211::-;32185:58;;;-1:-1:-1;;;;;32185:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32208:23;32185:58;;;32158:86;;32178:5;;32158:19;:86::i;:::-;32041:211;;;:::o;3129:106::-;3217:10;3129:106;:::o;1555:568::-;1996:4;2063:17;2108:7;1555:568;:::o;4320:129::-;1106:12;;;;;;;;:31;;;1122:15;:13;:15::i;:::-;1106:47;;;-1:-1:-1;1142:11:0;;;;1141:12;1106:47;1098:106;;;;-1:-1:-1;;;1098:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1217:19;1240:12;;;;;;1239:13;1263:99;;;;1298:12;:19;;-1:-1:-1;;;;1298:19:0;;;;;1332:18;1313:4;1332:18;;;1263:99;4378:26:::1;:24;:26::i;:::-;4415;:24;:26::i;:::-;1392:14:::0;1388:67;;;1438:5;1423:20;;-1:-1:-1;;1423:20:0;;;1388:67;4320:129;:::o;9889:651::-;10012:12;10038:14;10054;10072:26;10083:6;10091;10072:10;:26::i;:::-;10317:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10307:43;;;;;;10196:291;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10164:342;;;;;;;;;9889:651;-1:-1:-1;;;;;9889:651:0:o;32260:248::-;32431:68;;;-1:-1:-1;;;;;32431:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32454:27;32431:68;;;32404:96;;32424:5;;32404:19;:96::i;:::-;32260:248;;;;:::o;34457:774::-;34881:23;34907:69;34935:4;34907:69;;;;;;;;;;;;;;;;;34915:5;-1:-1:-1;;;;;34907:27:0;;;:69;;;;;:::i;:::-;34991:17;;34881:95;;-1:-1:-1;34991:21:0;34987:237;;35146:10;35135:30;;;;;;;;;;;;;;;-1:-1:-1;35135:30:0;35127:85;;;;-1:-1:-1;;;35127:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3062:59;1106:12;;;;;;;;:31;;;1122:15;:13;:15::i;:::-;1106:47;;;-1:-1:-1;1142:11:0;;;;1141:12;1106:47;1098:106;;;;-1:-1:-1;;;1098:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1217:19;1240:12;;;;;;1239:13;1263:99;;;;1298:12;:19;;-1:-1:-1;;;;1298:19:0;;;;;1332:18;1313:4;1332:18;;;1392:14;1388:67;;;1438:5;1423:20;;-1:-1:-1;;1423:20:0;;;3062:59;:::o;4457:196::-;1106:12;;;;;;;;:31;;;1122:15;:13;:15::i;:::-;1106:47;;;-1:-1:-1;1142:11:0;;;;1141:12;1106:47;1098:106;;;;-1:-1:-1;;;1098:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1217:19;1240:12;;;;;;1239:13;1263:99;;;;1298:12;:19;;-1:-1:-1;;;;1298:19:0;;;;;1332:18;1313:4;1332:18;;;1263:99;4525:17:::1;4545:12;:10;:12::i;:::-;4568:6;:18:::0;;;::::1;-1:-1:-1::0;;;;;4568:18:0;::::1;::::0;;::::1;::::0;;;4602:43:::1;::::0;4568:18;;-1:-1:-1;4568:18:0;-1:-1:-1;;4602:43:0::1;::::0;-1:-1:-1;;4602:43:0::1;1374:1;1392:14:::0;1388:67;;;1438:5;1423:20;;-1:-1:-1;;1423:20:0;;;4457:196;:::o;9448:349::-;9523:14;9539;9584:6;-1:-1:-1;;;;;9574:16:0;:6;-1:-1:-1;;;;;9574:16:0;;;9566:66;;;;-1:-1:-1;;;9566:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9671:6;-1:-1:-1;;;;;9662:15:0;:6;-1:-1:-1;;;;;9662:15:0;;:53;;9700:6;9708;9662:53;;;9681:6;9689;9662:53;9643:72;;-1:-1:-1;9643:72:0;-1:-1:-1;;;;;;9734:20:0;;9726:63;;;;;-1:-1:-1;;;9726:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9448:349;;;;;:::o;26929:229::-;27066:12;27098:52;27120:6;27128:4;27134:1;27137:12;27098:21;:52::i;:::-;27091:59;;26929:229;;;;;;:::o;28049:571::-;28219:12;28277:5;28252:21;:30;;28244:81;;;;-1:-1:-1;;;28244:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28344:18;28355:6;28344:10;:18::i;:::-;28336:60;;;;;-1:-1:-1;;;28336:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;28470:12;28484:23;28511:6;-1:-1:-1;;;;;28511:11:0;28530:5;28537:4;28511:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28469:73;;;;28560:52;28578:7;28587:10;28599:12;28560:17;:52::i;:::-;28553:59;28049:571;-1:-1:-1;;;;;;;28049:571:0:o;23989:444::-;24369:20;24417:8;;;23989:444::o;30698:777::-;30848:12;30877:7;30873:595;;;-1:-1:-1;30908:10:0;30901:17;;30873:595;31022:17;;:21;31018:439;;31285:10;31279:17;31346:15;31333:10;31329:2;31325:19;31318:44;31233:148;31428:12;31421:20;;-1:-1:-1;;;31421:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;:::o
Swarm Source
ipfs://3cd2088a29d59b0d2fc959462484018accc9c34777bea98d90284e609ccfcb58
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.