Overview
FTM Balance
FTM Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Initialize | 66305780 | 602 days ago | IN | 0 FTM | 0.01246387 |
Latest 25 internal transactions (View All)
Contract Source Code (Solidity)
/** *Submitted for verification at ftmscan.com on 2023-02-21 */ /** *v1.1.0 *0xc9ab1ab21358f4fc36cbbbe27f3b3ead423ec33b *Submitted for verification at FtmScan.com on 2022-11-03 */ /** * EQUALIZER EXCHANGE * The New Liquidity Hub of Fantom chain! * https://equalizer.exchange (Dapp) * https://discord.gg/MaMhbgHMby (Community) * * * Version: 1.3.8 * - Clarify Fee-Claims are once per veNFT per 7 days per pool * - Real-time Countdown * * * Contributors: * - Andre Cronje, Solidly.Exchange * - Velodrome.finance Team * - @smartcoding51 * - Sam 543#3017, Equalizer Team * * * SPDX-License-Identifier: UNLICENSED * */ // File: contracts/interfaces/IPairFactory.sol pragma solidity 0.8.9; interface IPairFactory { function isPaused() external view returns (bool); function allPairsLength() external view returns (uint); function isPair(address pair) external view returns (bool); function getFee(bool _stable) external view returns(uint256); function pairCodeHash() external pure returns (bytes32); function getPair(address tokenA, address token, bool stable) external view returns (address); function getInitializable() external view returns (address, address, bool); function createPair(address tokenA, address tokenB, bool stable) external returns (address pair); } // File: contracts/interfaces/IPairCallee.sol pragma solidity 0.8.9; interface IPairCallee { function hook(address sender, uint amount0, uint amount1, bytes calldata data) external; } // File: contracts/interfaces/IPairCallee.sol pragma solidity 0.8.9; interface IPair { function stable() external view returns (bool _s); } // File: contracts/interfaces/IERC20.sol pragma solidity 0.8.9; interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint); function transferFrom(address sender, address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // File: contracts/libraries/Math.sol pragma solidity 0.8.9; library Math { function max(uint a, uint b) internal pure returns (uint) { return a >= b ? a : b; } function min(uint a, uint b) internal pure returns (uint) { return a < b ? a : b; } function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } function cbrt(uint256 n) internal pure returns (uint256) { unchecked { uint256 x = 0; for (uint256 y = 1 << 255; y > 0; y >>= 3) { x <<= 1; uint256 z = 3 * x * (x + 1) + 1; if (n / y >= z) { n -= y * z; x += 1; } } return x; }} } // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } } // File: contracts/PairFees.sol pragma solidity 0.8.9; /** * @title Pair Fees * @notice used as a 1:1 pair relationship to split out fees, this ensures * that the curve does not need to be modified for LP shares */ contract PairFees is Initializable { address internal pair; // The pair it is bonded to address internal token0; // token0 of pair, saved localy and statically for gas optimization address internal token1; // Token1 of pair, saved localy and statically for gas optimization function initialize(address _token0, address _token1) public initializer { pair = msg.sender; token0 = _token0; token1 = _token1; } function _safeTransfer(address token,address to,uint256 value) internal { require(token.code.length > 0, "PairFees: invalid token"); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "PairFees: transfer failed"); } // Allow the pair to transfer fees to users function claimFeesFor(address recipient, uint amount0, uint amount1) external { require(msg.sender == pair, "Only pair contract can call"); if (amount0 > 0) _safeTransfer(token0, recipient, amount0); if (amount1 > 0) _safeTransfer(token1, recipient, amount1); } } // File: contracts/Pair.sol pragma solidity 0.8.9; contract Pair is Initializable { string public name; string public symbol; uint8 public constant decimals = 18; /// @notice Used to denote stable or volatile pair, not immutable since construction happens in the initialize method for CREATE2 deterministic addresses bool public stable; uint256 public totalSupply; mapping(address => mapping (address => uint)) public allowance; mapping(address => uint) public balanceOf; bytes32 internal DOMAIN_SEPARATOR; /// @dev keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 internal constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint) public nonces; uint256 internal constant MINIMUM_LIQUIDITY = 10**3; address public token0; address public token1; address public fees; address public factory; // Structure to capture time period obervations every 30 minutes, used for local oracles struct Observation { uint timestamp; uint reserve0Cumulative; uint reserve1Cumulative; } // Capture oracle reading every 30 minutes uint constant periodSize = 1800; Observation[] public observations; uint internal decimals0; uint internal decimals1; uint public reserve0; uint public reserve1; uint public blockTimestampLast; uint public reserve0CumulativeLast; uint public reserve1CumulativeLast; // index0 and index1 are used to accumulate fees, this is split out from normal trades to keep the swap "clean" // this further allows LP holders to easily claim fees for tokens they have/staked uint public index0; uint public index1; // position assigned to each LP to track their current index0 & index1 vs the global position mapping(address => uint) public supplyIndex0; mapping(address => uint) public supplyIndex1; // tracks the amount of unclaimed, but claimable tokens off of fees for token0 and token1 mapping(address => uint) public claimable0; mapping(address => uint) public claimable1; /// @dev simple re-entrancy check bool internal _locked; event Fees(address indexed sender, uint amount0, uint amount1); event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint reserve0, uint reserve1); event Claim(address indexed sender, address indexed recipient, uint amount0, uint amount1); event Transfer(address indexed from, address indexed to, uint amount); event Approval(address indexed owner, address indexed spender, uint amount); modifier lock() { require(!_locked, "No re-entrancy"); _locked = true; _; _locked = false; } function initialize() public initializer { factory = msg.sender; (address _token0, address _token1, bool _stable) = IPairFactory(msg.sender).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); PairFees pairFees = new PairFees(); pairFees.initialize(_token0, _token1); fees = address(pairFees); if (_stable) { name = string(abi.encodePacked("StableV1 AMM - ", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); symbol = string(abi.encodePacked("sAMM-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); } else { name = string(abi.encodePacked("VolatileV1 AMM - ", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); symbol = string(abi.encodePacked("vAMM-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); } decimals0 = 10**IERC20(_token0).decimals(); decimals1 = 10**IERC20(_token1).decimals(); observations.push(Observation(block.timestamp, 0, 0)); } function observationLength() external view returns (uint) { return observations.length; } function lastObservation() public view returns (Observation memory) { return observations[observations.length-1]; } function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1) { return (decimals0, decimals1, reserve0, reserve1, stable, token0, token1); } function tokens() external view returns (address, address) { return (token0, token1); } /// @dev claim accumulated but unclaimed fees (viewable via claimable0 and claimable1) function claimFees() external returns (uint claimed0, uint claimed1) { _updateFor(msg.sender); claimed0 = claimable0[msg.sender]; claimed1 = claimable1[msg.sender]; if (claimed0 > 0 || claimed1 > 0) { claimable0[msg.sender] = 0; claimable1[msg.sender] = 0; PairFees(fees).claimFeesFor(msg.sender, claimed0, claimed1); emit Claim(msg.sender, msg.sender, claimed0, claimed1); } } /// @dev Accrue fees on token0 function _update0(uint amount) internal { _safeTransfer(token0, fees, amount); // transfer the fees out to PairFees uint256 _ratio = amount * 1e18 / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { index0 += _ratio; } emit Fees(msg.sender, amount, 0); } /// @dev Accrue fees on token1 function _update1(uint amount) internal { _safeTransfer(token1, fees, amount); uint256 _ratio = amount * 1e18 / totalSupply; if (_ratio > 0) { index1 += _ratio; } emit Fees(msg.sender, 0, amount); } /** * @notice This function must be called on any balance changes, otherwise can be used to infinitely claim fees * Fees are segregated from core funds, so fees can never put liquidity at risk */ function _updateFor(address recipient) internal { uint _supplied = balanceOf[recipient]; // get LP balance of `recipient` if (_supplied > 0) { uint _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient uint _supplyIndex1 = supplyIndex1[recipient]; uint _index0 = index0; // get global index0 for accumulated fees uint _index1 = index1; supplyIndex0[recipient] = _index0; // update user current position to global position supplyIndex1[recipient] = _index1; uint _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued uint _delta1 = _index1 - _supplyIndex1; if (_delta0 > 0) { uint _share = _supplied * _delta0 / 1e18; // add accrued difference for each supplied token claimable0[recipient] += _share; } if (_delta1 > 0) { uint _share = _supplied * _delta1 / 1e18; claimable1[recipient] += _share; } } else { supplyIndex0[recipient] = index0; // new users are set to the default global state supplyIndex1[recipient] = index1; } } function getReserves() public view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = blockTimestampLast; } /// @dev update reserves and, on the first call per block, price accumulators function _update(uint balance0, uint balance1, uint _reserve0, uint _reserve1) internal { uint blockTimestamp = block.timestamp; uint timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { reserve0CumulativeLast += _reserve0 * timeElapsed; reserve1CumulativeLast += _reserve1 * timeElapsed; } Observation memory _point = lastObservation(); timeElapsed = blockTimestamp - _point.timestamp; // compare the last observation with current timestamp, if greater than 30 minutes, record a new event if (timeElapsed > periodSize) { observations.push(Observation(blockTimestamp, reserve0CumulativeLast, reserve1CumulativeLast)); } reserve0 = balance0; reserve1 = balance1; blockTimestampLast = blockTimestamp; emit Sync(reserve0, reserve1); } /// @dev produces the cumulative price using counterfactuals to save gas and avoid a call to sync. function currentCumulativePrices() public view returns (uint reserve0Cumulative, uint reserve1Cumulative, uint blockTimestamp) { blockTimestamp = block.timestamp; reserve0Cumulative = reserve0CumulativeLast; reserve1Cumulative = reserve1CumulativeLast; // if time has elapsed since the last update on the pair, mock the accumulated price values (uint _reserve0, uint _reserve1, uint _blockTimestampLast) = getReserves(); if (_blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint timeElapsed = blockTimestamp - _blockTimestampLast; reserve0Cumulative += _reserve0 * timeElapsed; reserve1Cumulative += _reserve1 * timeElapsed; } } /// @dev gives the current twap price measured from amountIn * tokenIn gives amountOut function current(address tokenIn, uint amountIn) external view returns (uint amountOut) { Observation memory _observation = lastObservation(); (uint reserve0Cumulative, uint reserve1Cumulative,) = currentCumulativePrices(); if (block.timestamp == _observation.timestamp) { _observation = observations[observations.length-2]; } uint timeElapsed = block.timestamp - _observation.timestamp; uint _reserve0 = (reserve0Cumulative - _observation.reserve0Cumulative) / timeElapsed; uint _reserve1 = (reserve1Cumulative - _observation.reserve1Cumulative) / timeElapsed; amountOut = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); } /// @dev as per `current`, however allows user configured granularity, up to the full window size function quote(address tokenIn, uint amountIn, uint granularity) external view returns (uint amountOut) { uint [] memory _prices = sample(tokenIn, amountIn, granularity, 1); uint priceAverageCumulative; for (uint i = 0; i < _prices.length; i++) { priceAverageCumulative += _prices[i]; } return priceAverageCumulative / granularity; } /// @dev returns a memory set of twap prices function prices(address tokenIn, uint amountIn, uint points) external view returns (uint[] memory) { return sample(tokenIn, amountIn, points, 1); } function sample(address tokenIn, uint amountIn, uint points, uint window) public view returns (uint[] memory) { uint[] memory _prices = new uint[](points); uint length = observations.length-1; uint i = length - (points * window); uint nextIndex = 0; uint index = 0; for (; i < length; i+=window) { nextIndex = i + window; uint timeElapsed = observations[nextIndex].timestamp - observations[i].timestamp; uint _reserve0 = (observations[nextIndex].reserve0Cumulative - observations[i].reserve0Cumulative) / timeElapsed; uint _reserve1 = (observations[nextIndex].reserve1Cumulative - observations[i].reserve1Cumulative) / timeElapsed; _prices[index] = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); // index < length; length cannot overflow unchecked { index = index + 1; } } return _prices; } /** * @notice this low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks * standard uniswap v2 implementation */ function mint(address to) external lock returns (uint liquidity) { (uint _reserve0, uint _reserve1) = (reserve0, reserve1); uint _balance0 = IERC20(token0).balanceOf(address(this)); uint _balance1 = IERC20(token1).balanceOf(address(this)); uint _amount0 = _balance0 - _reserve0; uint _amount1 = _balance1 - _reserve1; uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee if (_totalSupply == 0) { liquidity = Math.sqrt(_amount0 * _amount1) - MINIMUM_LIQUIDITY; _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens } else { liquidity = Math.min(_amount0 * _totalSupply / _reserve0, _amount1 * _totalSupply / _reserve1); } require(liquidity > 0, "ILM"); // Pair: INSUFFICIENT_LIQUIDITY_MINTED _mint(to, liquidity); _update(_balance0, _balance1, _reserve0, _reserve1); emit Mint(msg.sender, _amount0, _amount1); } /** * @notice this low-level function should be called from a contract which performs important safety checks * standard uniswap v2 implementation */ function burn(address to) external lock returns (uint amount0, uint amount1) { (uint _reserve0, uint _reserve1) = (reserve0, reserve1); (address _token0, address _token1) = (token0, token1); uint _balance0 = IERC20(_token0).balanceOf(address(this)); uint _balance1 = IERC20(_token1).balanceOf(address(this)); uint _liquidity = balanceOf[address(this)]; uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee amount0 = _liquidity * _balance0 / _totalSupply; // using balances ensures pro-rata distribution amount1 = _liquidity * _balance1 / _totalSupply; // using balances ensures pro-rata distribution require(amount0 > 0 && amount1 > 0, "ILB"); // Pair: INSUFFICIENT_LIQUIDITY_BURNED _burn(address(this), _liquidity); _safeTransfer(_token0, to, amount0); _safeTransfer(_token1, to, amount1); _balance0 = IERC20(_token0).balanceOf(address(this)); _balance1 = IERC20(_token1).balanceOf(address(this)); _update(_balance0, _balance1, _reserve0, _reserve1); emit Burn(msg.sender, amount0, amount1, to); } /// @dev this low-level function should be called from a contract which performs important safety checks function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { require(!IPairFactory(factory).isPaused()); require(amount0Out > 0 || amount1Out > 0, "IOA"); // Pair: INSUFFICIENT_OUTPUT_AMOUNT (uint _reserve0, uint _reserve1) = (reserve0, reserve1); require(amount0Out < _reserve0 && amount1Out < _reserve1, "IL"); // Pair: INSUFFICIENT_LIQUIDITY uint _balance0; uint _balance1; { // scope for _token{0,1}, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); require(to != _token0 && to != _token1, "IT"); // Pair: INVALID_TO if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens if (data.length > 0) IPairCallee(to).hook(msg.sender, amount0Out, amount1Out, data); // callback, used for flash loans _balance0 = IERC20(_token0).balanceOf(address(this)); _balance1 = IERC20(_token1).balanceOf(address(this)); } uint amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0; uint amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0; require(amount0In > 0 || amount1In > 0, "IIA"); // Pair: INSUFFICIENT_INPUT_AMOUNT { // scope for reserve{0,1}Adjusted, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); if (amount0In > 0) _update0(amount0In * IPairFactory(factory).getFee(stable) / 10000); // accrue fees for token0 and move them out of pool if (amount1In > 0) _update1(amount1In * IPairFactory(factory).getFee(stable) / 10000); // accrue fees for token1 and move them out of pool _balance0 = IERC20(_token0).balanceOf(address(this)); // since we removed tokens, we need to reconfirm balances, can also simply use previous balance - amountIn/ 10000, but doing balanceOf again as safety check _balance1 = IERC20(_token1).balanceOf(address(this)); // The curve, either x3y+y3x for stable pools, or x*y for volatile pools require(_k(_balance0, _balance1) >= _k(_reserve0, _reserve1), "K"); // Pair: K } _update(_balance0, _balance1, _reserve0, _reserve1); emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); } /// @dev force balances to match reserves function skim(address to) external lock { (address _token0, address _token1) = (token0, token1); _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)) - (reserve0)); _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)) - (reserve1)); } /// @dev force reserves to match balances function sync() external lock { _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1); } function _f(uint x0, uint y) internal pure returns (uint) { return x0*(y*y/1e18*y/1e18)/1e18+(x0*x0/1e18*x0/1e18)*y/1e18; } function _d(uint x0, uint y) internal pure returns (uint) { return 3*x0*(y*y/1e18)/1e18+(x0*x0/1e18*x0/1e18); } function _get_y(uint x0, uint xy, uint y) internal pure returns (uint) { for (uint i = 0; i < 255; i++) { uint y_prev = y; uint k = _f(x0, y); if (k < xy) { uint dy = (xy - k)*1e18/_d(x0, y); y = y + dy; } else { uint dy = (k - xy)*1e18/_d(x0, y); y = y - dy; } if (y > y_prev) { if (y - y_prev <= 1) { return y; } } else { if (y_prev - y <= 1) { return y; } } } return y; } function getAmountOut(uint amountIn, address tokenIn) external view returns (uint) { (uint _reserve0, uint _reserve1) = (reserve0, reserve1); amountIn -= amountIn * IPairFactory(factory).getFee(stable) / 10000; // remove fee from amount received return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); } function _getAmountOut(uint amountIn, address tokenIn, uint _reserve0, uint _reserve1) internal view returns (uint) { if (stable) { uint xy = _k(_reserve0, _reserve1); _reserve0 = _reserve0 * 1e18 / decimals0; _reserve1 = _reserve1 * 1e18 / decimals1; (uint reserveA, uint reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0); amountIn = tokenIn == token0 ? amountIn * 1e18 / decimals0 : amountIn * 1e18 / decimals1; uint y = reserveB - _get_y(amountIn+reserveA, xy, reserveB); return y * (tokenIn == token0 ? decimals1 : decimals0) / 1e18; } else { (uint reserveA, uint reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0); return amountIn * reserveB / (reserveA + amountIn); } } function _k(uint x, uint y) internal view returns (uint) { if (stable) { uint _x = x * 1e18 / decimals0; uint _y = y * 1e18 / decimals1; uint _a = (_x * _y) / 1e18; uint _b = ((_x * _x) / 1e18 + (_y * _y) / 1e18); return _a * _b / 1e18; // x3y+y3x >= k } else { return x * y; // xy >= k } } function _mint(address dst, uint amount) internal { _updateFor(dst); // balances must be updated on mint/burn/transfer totalSupply += amount; balanceOf[dst] += amount; emit Transfer(address(0), dst, amount); } function _burn(address dst, uint amount) internal { _updateFor(dst); totalSupply -= amount; balanceOf[dst] -= amount; emit Transfer(dst, address(0), amount); } function approve(address spender, uint amount) external returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { require(deadline >= block.timestamp, "Pair: EXPIRED"); DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes("1")), block.chainid, address(this) ) ); bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "Pair: INVALID_SIGNATURE"); allowance[owner][spender] = value; emit Approval(owner, spender, value); } function transfer(address dst, uint amount) external returns (bool) { _transferTokens(msg.sender, dst, amount); return true; } function transferFrom(address src, address dst, uint amount) external returns (bool) { address spender = msg.sender; uint spenderAllowance = allowance[src][spender]; if (spender != src && spenderAllowance != type(uint).max) { uint newAllowance = spenderAllowance - amount; allowance[src][spender] = newAllowance; emit Approval(src, spender, newAllowance); } _transferTokens(src, dst, amount); return true; } function _transferTokens(address src, address dst, uint amount) internal { _updateFor(src); // update fee position for src _updateFor(dst); // update fee position for dst balanceOf[src] -= amount; balanceOf[dst] += amount; emit Transfer(src, dst, amount); } function _safeTransfer(address token,address to,uint256 value) internal { require(token.code.length > 0, "Pair: invalid token"); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "Pair: transfer failed"); } } // File: contracts/factories/PairFactory.sol pragma solidity 0.8.9; contract PairFactory is Initializable { bool public isPaused; address public pauser; address public pendingPauser; uint256 public stableFee; uint256 public volatileFee; uint256 public constant MAX_FEE = 30; // 0.3% address public feeManager; address public pendingFeeManager; mapping(address => mapping(address => mapping(bool => address))) public getPair; address[] public allPairs; mapping(address => bool) public isPair; // simplified check if its a pair, given that `stable` flag might not be available in peripherals address internal _temp0; address internal _temp1; bool internal _temp; /// VARIBALES ARE STATEFUL ! DONT MESS WITH THEM SLOTS !! /// ADDITIONAL SLOTS ATTACHED TO TAIL -- DONT DELETE ANY VARIABLES, ONLY ADD NEW ONES TO THE TAIL!!! /// (There are a limited number of slots! (almost infinte, dont worry;)) /// v1.3.11 //(Using a new variable instead at Tail to not cause slot collision, as this contract will be used as Equalizer's PairFactory implementation) uint256 public MAX_FEE_NEW = 1337; // 13.37% mapping(address => uint256) public feesOverrides; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Such events, much eventful * @notice Events are stateless, ordering doesn't matter. */ event PairCreated(address indexed token0, address indexed token1, bool stable, address pair, uint); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * wow functions, very fun * @notice Functions are stateless, ordering doesn't matter. */ function initialize() public initializer { pauser = msg.sender; isPaused = false; feeManager = msg.sender; stableFee = 2; // 0.02% volatileFee = 20; // 0.2% } function allPairsLength() external view returns (uint) { return allPairs.length; } function setPauser(address _pauser) external { require(msg.sender == pauser, "PairFactory: not a pauser"); pendingPauser = _pauser; } function acceptPauser() external { require(msg.sender == pendingPauser, "PairFactory: not a pendingPauser"); pauser = pendingPauser; } function setPause(bool _state) external { require(msg.sender == pauser, "PairFactory: not a pauser"); isPaused = _state; } function setFeeManager(address _feeManager) external { require(msg.sender == feeManager, "not fee manager"); pendingFeeManager = _feeManager; } function acceptFeeManager() external { require(msg.sender == pendingFeeManager, "not pending fee manager"); feeManager = pendingFeeManager; } function setFee(bool _stable, uint256 _fee) external { require(msg.sender == feeManager, "not fee manager"); require(_fee <= MAX_FEE_NEW, "fee too high"); require(_fee != 0, "fee must be nonzero"); if (_stable) { stableFee = _fee; } else { volatileFee = _fee; } } function setFeesOverrides(address _pair, uint256 _fee) external { require(msg.sender == feeManager, "not fee manager"); require(_fee <= MAX_FEE_NEW, "fee too high"); require(_fee != 0, "fee must be nonzero"); feesOverrides[_pair] = _fee; } function getRealFee(address _pair) public view returns(uint256) { /// to get base fees, call `stableFee()` or `volatileFee()` uint _fo = feesOverrides[ _pair ]; if( _fo > 0 ) { return _fo; } else{ return IPair(_pair).stable() ? stableFee : volatileFee; } } function getFee(bool _stable) public view returns(uint256) { /// This method was changed in v1.3.11 /// This method, when called by an actual Pair contract itself, would return the real fees. /// If simply read, it will show basic fees: stableFee, or the volatileFee. /// Please use the `getRealFees` method instead for your Analytics / Dapps / Usecases! /// If you want to request a flashloan from any Pair, please query `getRealFee` instead. address _c = msg.sender; if(isPair[ _c ]) { uint _fo = feesOverrides[ _c ]; if( _fo > 0 ) { return _fo; } else return _stable ? stableFee : volatileFee; //non-overridden fee is base fee. } else return _stable ? stableFee : volatileFee; //non-pair callers (_c) see base fee. } /* PAST IMPLEMENTAION OF `getFee() FOR FUTURE REFERENCE function getFee(bool _stable) public view returns(uint256) { return _stable ? stableFee : volatileFee; } */ function pairCodeHash() external pure returns (bytes32) { return keccak256(type(Pair).creationCode); } function getInitializable() external view returns (address, address, bool) { return (_temp0, _temp1, _temp); } function createPair(address tokenA, address tokenB, bool stable) external returns (address pair) { require(tokenA != tokenB, "IA"); // Pair: IDENTICAL_ADDRESSES (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), "ZA"); // Pair: ZERO_ADDRESS require(getPair[token0][token1][stable] == address(0), "PE"); // Pair: PAIR_EXISTS - single check is sufficient bytes32 salt = keccak256(abi.encodePacked(token0, token1, stable)); // notice salt includes stable as well, 3 parameters (_temp0, _temp1, _temp) = (token0, token1, stable); Pair newPair = new Pair{salt:salt}(); newPair.initialize(); pair = address(newPair); getPair[token0][token1][stable] = pair; getPair[token1][token0][stable] = pair; // populate mapping in the reverse direction allPairs.push(pair); isPair[pair] = true; emit PairCreated(token0, token1, stable, pair, allPairs.length); } function hotload() external { require(msg.sender == feeManager, "Team MS Only!"); /// v1.3.11 MAX_FEE_NEW = 1337; // 13.37% } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE_NEW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesOverrides","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializable","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"getRealFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hotload","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingFeeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingPauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFeesOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pauser","type":"address"}],"name":"setPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052610539600b5534801561001657600080fd5b506154f4806100266000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806382dfdce4116100f9578063bc063e1a11610097578063e1f76b4411610071578063e1f76b44146103a9578063e5e31b13146103bc578063eb13c4cf146103df578063f94c53c71461041757600080fd5b8063bc063e1a1461037b578063bedb86fb14610383578063d0fb02031461039657600080fd5b80639aab9248116100d35780639aab92481461032e5780639fd0506d14610336578063a336252c14610350578063b187bd261461035857600080fd5b806382dfdce4146102f55780638a4fa0d2146103085780639a7165e41461031b57600080fd5b80634e24f35e11610166578063574f2ba311610140578063574f2ba3146102985780636652f0bf146102a05780636801cc30146102b35780638129fc1c146102ed57600080fd5b80634e24f35e1461025c5780635084ed031461027c578063512b45ea1461028557600080fd5b80632b724a28116101a25780632b724a28146102165780632d88af4a1461022d57806340bbd77514610240578063472d35b91461024957600080fd5b8063167a6f90146101c95780631e3dd18b146101d3578063269eec3a14610203575b600080fd5b6101d161041f565b005b6101e66101e1366004610e4c565b6104ab565b6040516001600160a01b0390911681526020015b60405180910390f35b6101d1610211366004610e81565b6104d5565b61021f600b5481565b6040519081526020016101fa565b6101d161023b366004610eab565b61059f565b61021f60025481565b6101d1610257366004610eab565b61061e565b61021f61026a366004610eab565b600c6020526000908152604090205481565b61021f60035481565b61021f610293366004610ed4565b61066a565b60075461021f565b61021f6102ae366004610eab565b6106dc565b6101e66102c1366004610ef1565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6101d161077e565b6101e6610303366004610ef1565b6108c8565b6005546101e6906001600160a01b031681565b6001546101e6906001600160a01b031681565b61021f610c04565b6000546101e690630100000090046001600160a01b031681565b6101d1610c36565b60005461036b9062010000900460ff1681565b60405190151581526020016101fa565b61021f601e81565b6101d1610391366004610ed4565b610c88565b6004546101e6906001600160a01b031681565b6101d16103b7366004610f38565b610d01565b61036b6103ca366004610eab565b60086020526000908152604090205460ff1681565b600954600a54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff161515908201526060016101fa565b6101d1610dc1565b6001546001600160a01b0316331461047e5760405162461bcd60e51b815260206004820181905260248201527f50616972466163746f72793a206e6f7420612070656e64696e6750617573657260448201526064015b60405180910390fd5b600154600080546301000000600160b81b0319166001600160a01b03909216630100000002919091179055565b600781815481106104bb57600080fd5b6000918252602090912001546001600160a01b0316905081565b6004546001600160a01b031633146104ff5760405162461bcd60e51b815260040161047590610f56565b600b548111156105405760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610475565b806105835760405162461bcd60e51b8152602060048201526013602482015272666565206d757374206265206e6f6e7a65726f60681b6044820152606401610475565b6001600160a01b039091166000908152600c6020526040902055565b600054630100000090046001600160a01b031633146105fc5760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b6044820152606401610475565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031633146106485760405162461bcd60e51b815260040161047590610f56565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b3360008181526008602052604081205490919060ff16156106c4576001600160a01b0381166000908152600c602052604090205480156106ab579392505050565b836106b8576003546106bc565b6002545b949350505050565b826106d1576003546106d5565b6002545b9392505050565b6001600160a01b0381166000908152600c602052604081205480156107015792915050565b826001600160a01b03166322be3de16040518163ffffffff1660e01b815260040160206040518083038186803b15801561073a57600080fd5b505afa15801561074e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107729190610f7f565b6106d1576003546106d5565b600054610100900460ff161580801561079e5750600054600160ff909116105b806107b85750303b1580156107b8575060005460ff166001145b61081b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610475565b6000805460ff19166001179055801561083e576000805461ff0019166101001790555b6000805462010000600160b81b031916336301000000810262ff0000191691909117909155600480546001600160a01b031916909117905560028055601460035580156108c5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000826001600160a01b0316846001600160a01b031614156109115760405162461bcd60e51b8152602060048201526002602482015261494160f01b6044820152606401610475565b600080846001600160a01b0316866001600160a01b031610610934578486610937565b85855b90925090506001600160a01b0382166109775760405162461bcd60e51b81526020600482015260026024820152615a4160f01b6044820152606401610475565b6001600160a01b03828116600090815260066020908152604080832085851684528252808320881515845290915290205416156109db5760405162461bcd60e51b8152602060048201526002602482015261504560f01b6044820152606401610475565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600a80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600980549288169290911691909117905591506000908290610a8390610e3f565b8190604051809103906000f5905080158015610aa3573d6000803e3d6000fd5b509050806001600160a01b0316638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ae157600080fd5b505af1158015610af5573d6000803e3d6000fd5b505050506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560078054600181810183557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889091018054909a1687179099558587526008855295839020805460ff19169098179097559354815196875291860192909252908401529296508692917fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a3505050509392505050565b600060405180602001610c1690610e3f565b6020820181038252601f19601f8201166040525080519060200120905090565b6004546001600160a01b03163314610c805760405162461bcd60e51b815260206004820152600d60248201526c5465616d204d53204f6e6c792160981b6044820152606401610475565b610539600b55565b600054630100000090046001600160a01b03163314610ce55760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b6044820152606401610475565b60008054911515620100000262ff000019909216919091179055565b6004546001600160a01b03163314610d2b5760405162461bcd60e51b815260040161047590610f56565b600b54811115610d6c5760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610475565b80610daf5760405162461bcd60e51b8152602060048201526013602482015272666565206d757374206265206e6f6e7a65726f60681b6044820152606401610475565b8115610dbb5760025550565b60035550565b6005546001600160a01b03163314610e1b5760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e616765720000000000000000006044820152606401610475565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b61452280610f9d83390190565b600060208284031215610e5e57600080fd5b5035919050565b80356001600160a01b0381168114610e7c57600080fd5b919050565b60008060408385031215610e9457600080fd5b610e9d83610e65565b946020939093013593505050565b600060208284031215610ebd57600080fd5b6106d582610e65565b80151581146108c557600080fd5b600060208284031215610ee657600080fd5b81356106d581610ec6565b600080600060608486031215610f0657600080fd5b610f0f84610e65565b9250610f1d60208501610e65565b91506040840135610f2d81610ec6565b809150509250925092565b60008060408385031215610f4b57600080fd5b8235610e9d81610ec6565b6020808252600f908201526e3737ba103332b29036b0b730b3b2b960891b604082015260600190565b600060208284031215610f9157600080fd5b81516106d581610ec656fe608060405234801561001057600080fd5b50614502806100206000396000f3fe608060405234801561001057600080fd5b506004361061028a5760003560e01c80638129fc1c1161015c578063bda39cad116100ce578063d294f09311610087578063d294f0931461064e578063d505accf14610656578063dd62ed3e14610669578063ebeb31db14610694578063f140a35a1461069c578063fff6cae9146106af57600080fd5b8063bda39cad14610604578063bf944dbc1461060d578063c245febc14610616578063c45a01551461061f578063c5700a0214610632578063d21220a71461063b57600080fd5b80639d63848a116101205780639d63848a146105655780639e8cc04b1461058b5780639f767c881461059e578063a1ac4d13146105be578063a9059cbb146105de578063bc25cf77146105f157600080fd5b80638129fc1c146104f057806389afcb44146104f85780638a7b8cf21461052057806395d89b411461054a5780639af1d35a1461055257600080fd5b8063252c09d711610200578063517b3f82116101b9578063517b3f821461046e5780635881c475146104815780635a76f25e146104945780636a6278421461049d57806370a08231146104b05780637ecebe00146104d057600080fd5b8063252c09d7146103b4578063313ce567146103c757806332c0defd146103e1578063392f37e9146103ea578063443cb4bc146104455780634d5a9f8a1461044e57600080fd5b806313345fe11161025257806313345fe11461033557806318160ddd146103555780631df8c7171461036c578063205aabf11461037457806322be3de11461039457806323b872dd146103a157600080fd5b8063022c0d9f1461028f57806306fdde03146102a45780630902f1ac146102c2578063095ea7b3146102e75780630dfe16811461030a575b600080fd5b6102a261029d366004613705565b6106b7565b005b6102ac610dad565b6040516102b991906137cb565b60405180910390f35b6010546011546012545b604080519384526020840192909252908201526060016102b9565b6102fa6102f53660046137fe565b610e3b565b60405190151581526020016102b9565b60095461031d906001600160a01b031681565b6040516001600160a01b0390911681526020016102b9565b61034861034336600461382a565b610ea8565b6040516102b99190613865565b61035e60045481565b6040519081526020016102b9565b6102cc6110a4565b61035e6103823660046138a9565b60186020526000908152604090205481565b6003546102fa9060ff1681565b6102fa6103af3660046138c6565b611113565b6102cc6103c2366004613907565b6111dc565b6103cf601281565b60405160ff90911681526020016102b9565b61035e60155481565b600e54600f54601054601154600354600954600a5460408051978852602088019690965294860193909352606085019190915260ff16151560808401526001600160a01b0390811660a08401521660c082015260e0016102b9565b61035e60105481565b61035e61045c3660046138a9565b60196020526000908152604090205481565b61035e61047c3660046137fe565b61120f565b61034861048f366004613920565b6112f8565b61035e60115481565b61035e6104ab3660046138a9565b611307565b61035e6104be3660046138a9565b60066020526000908152604090205481565b61035e6104de3660046138a9565b60086020526000908152604090205481565b6102a261156a565b61050b6105063660046138a9565b611e24565b604080519283526020830191909152016102b9565b61052861216a565b60408051825181526020808401519082015291810151908201526060016102b9565b6102ac6121ea565b600b5461031d906001600160a01b031681565b600954600a54604080516001600160a01b039384168152929091166020830152016102b9565b61035e610599366004613920565b6121f7565b61035e6105ac3660046138a9565b60176020526000908152604090205481565b61035e6105cc3660046138a9565b601a6020526000908152604090205481565b6102fa6105ec3660046137fe565b612264565b6102a26105ff3660046138a9565b61227a565b61035e60165481565b61035e60135481565b61035e60145481565b600c5461031d906001600160a01b031681565b61035e60125481565b600a5461031d906001600160a01b031681565b61050b612391565b6102a2610664366004613964565b61249b565b61035e6106773660046139d5565b600560209081526000928352604080842090915290825290205481565b600d5461035e565b61035e6106aa366004613a0e565b6127a3565b6102a261286b565b601b5460ff16156106e35760405162461bcd60e51b81526004016106da90613a33565b60405180910390fd5b601b805460ff19166001179055600c54604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561073557600080fd5b505afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190613a6b565b1561077757600080fd5b60008511806107865750600084115b6107b85760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064016106da565b60105460115481871080156107cc57508086105b6107fd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b60448201526064016106da565b600954600a5460009182916001600160a01b0391821691908116908916821480159061083b5750806001600160a01b0316896001600160a01b031614155b61086c5760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106da565b8a1561087d5761087d828a8d6129aa565b891561088e5761088e818a8c6129aa565b86156108fb57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906108c89033908f908f908e908e90600401613a86565b600060405180830381600087803b1580156108e257600080fd5b505af11580156108f6573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109729190613ad2565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a082319060240160206040518083038186803b1580156109b457600080fd5b505afa1580156109c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ec9190613ad2565b92505050600089856109fe9190613b01565b8311610a0b576000610a1f565b610a158a86613b01565b610a1f9084613b01565b90506000610a2d8a86613b01565b8311610a3a576000610a4e565b610a448a86613b01565b610a4e9084613b01565b90506000821180610a5f5750600081115b610a915760405162461bcd60e51b815260206004820152600360248201526249494160e81b60448201526064016106da565b600954600a546001600160a01b0391821691168315610b4f57600c54600354604051632895a2f560e11b815260ff90911615156004820152610b4f91612710916001600160a01b039091169063512b45ea9060240160206040518083038186803b158015610afe57600080fd5b505afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190613ad2565b610b409087613b18565b610b4a9190613b37565b612b0d565b8215610bfa57600c54600354604051632895a2f560e11b815260ff90911615156004820152610bfa91612710916001600160a01b039091169063512b45ea9060240160206040518083038186803b158015610ba957600080fd5b505afa158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190613ad2565b610beb9086613b18565b610bf59190613b37565b612bac565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015610c3957600080fd5b505afa158015610c4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c719190613ad2565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a082319060240160206040518083038186803b158015610cb357600080fd5b505afa158015610cc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ceb9190613ad2565b9450610cf78888612c44565b610d018787612c44565b1015610d335760405162461bcd60e51b81526020600482015260016024820152604b60f81b60448201526064016106da565b5050610d4184848888612d3d565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a35050601b805460ff19169055505050505050505050565b60018054610dba90613b59565b80601f0160208091040260200160405190810160405280929190818152602001828054610de690613b59565b8015610e335780601f10610e0857610100808354040283529160200191610e33565b820191906000526020600020905b815481529060010190602001808311610e1657829003601f168201915b505050505081565b3360008181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610e969086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115610ec557610ec5613b8e565b604051908082528060200260200182016040528015610eee578160200160208202803683370190505b50600d54909150600090610f0490600190613b01565b90506000610f128587613b18565b610f1c9083613b01565b90506000805b8383101561109457610f348784613ba4565b91506000600d8481548110610f4b57610f4b613bbc565b906000526020600020906003020160000154600d8481548110610f7057610f70613bbc565b906000526020600020906003020160000154610f8c9190613b01565b9050600081600d8681548110610fa457610fa4613bbc565b906000526020600020906003020160010154600d8681548110610fc957610fc9613bbc565b906000526020600020906003020160010154610fe59190613b01565b610fef9190613b37565b9050600082600d878154811061100757611007613bbc565b906000526020600020906003020160020154600d878154811061102c5761102c613bbc565b9060005260206000209060030201600201546110489190613b01565b6110529190613b37565b90506110608c8e8484612ed1565b88858151811061107257611072613bbc565b602090810291909101015250505060010161108d8784613ba4565b9250610f22565b509293505050505b949350505050565b60135460145442600080806110c26010546011546012549192909190565b92509250925083811461110b5760006110db8286613b01565b90506110e78185613b18565b6110f19088613ba4565b96506110fd8184613b18565b6111079087613ba4565b9550505b505050909192565b6001600160a01b03831660008181526005602090815260408083203380855292528220549192909190821480159061114d57506000198114155b156111c357600061115e8583613b01565b6001600160a01b038881166000818152600560209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6111ce868686613072565b6001925050505b9392505050565b600d81815481106111ec57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b60008061121a61216a565b90506000806112276110a4565b508451919350915042141561129057600d805461124690600290613b01565b8154811061125657611256613bbc565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b825160009061129f9042613b01565b90506000818560200151856112b49190613b01565b6112be9190613b37565b90506000828660400151856112d39190613b01565b6112dd9190613b37565b90506112eb888a8484612ed1565b9998505050505050505050565b606061109c8484846001610ea8565b601b5460009060ff161561132d5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff191660011790556010546011546009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561138457600080fd5b505afa158015611398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bc9190613ad2565b600a546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b15801561140557600080fd5b505afa158015611419573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143d9190613ad2565b9050600061144b8584613b01565b905060006114598584613b01565b60045490915080611497576103e86114796114748486613b18565b613132565b6114839190613b01565b975061149260006103e86131a2565b6114cc565b6114c9876114a58386613b18565b6114af9190613b37565b876114ba8486613b18565b6114c49190613b37565b613235565b97505b600088116115025760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b60448201526064016106da565b61150c89896131a2565b61151885858989612d3d565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25050601b805460ff19169055509395945050505050565b600054610100900460ff161580801561158a5750600054600160ff909116105b806115a45750303b1580156115a4575060005460ff166001145b6116075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106da565b6000805460ff19166001179055801561162a576000805461ff0019166101001790555b600c80546001600160a01b031916339081179091556040805163eb13c4cf60e01b815290516000928392839263eb13c4cf91600480820192606092909190829003018186803b15801561167c57600080fd5b505afa158015611690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b49190613bd2565b6003805482151560ff19909116179055600a80546001600160a01b038085166001600160a01b0319928316179092556009805492861692909116919091179055604051929550909350915060009061170b9061364a565b604051809103906000f080158015611727573d6000803e3d6000fd5b5060405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529192509082169063485cc95590604401600060405180830381600087803b15801561177757600080fd5b505af115801561178b573d6000803e3d6000fd5b5050600b80546001600160a01b0319166001600160a01b038516179055505081156119f557836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e957600080fd5b505afa1580156117fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118259190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561185e57600080fd5b505afa158015611872573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261189a9190810190613c1a565b6040516020016118ab929190613cc7565b604051602081830303815290604052600190805190602001906118cf929190613657565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561190957600080fd5b505afa15801561191d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119459190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561197e57600080fd5b505afa158015611992573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119ba9190810190613c1a565b6040516020016119cb929190613d1e565b604051602081830303815290604052600290805190602001906119ef929190613657565b50611c36565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611a2e57600080fd5b505afa158015611a42573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a6a9190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611aa357600080fd5b505afa158015611ab7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611adf9190810190613c1a565b604051602001611af0929190613d6b565b60405160208183030381529060405260019080519060200190611b14929190613657565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b4e57600080fd5b505afa158015611b62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b8a9190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bc357600080fd5b505afa158015611bd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bff9190810190613c1a565b604051602001611c10929190613dc4565b60405160208183030381529060405260029080519060200190611c34929190613657565b505b836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611c6f57600080fd5b505afa158015611c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca79190613de4565b611cb290600a613ee5565b600e81905550826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611cf157600080fd5b505afa158015611d05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d299190613de4565b611d3490600a613ee5565b600f55505060408051606081018252428152600060208201818152928201818152600d8054600181018255925291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb560039092029182015591517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb6830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb79091015550508015611e21576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b601b54600090819060ff1615611e4c5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff19166001179055601054601154600954600a546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a082319060240160206040518083038186803b158015611eae57600080fd5b505afa158015611ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee69190613ad2565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015611f2b57600080fd5b505afa158015611f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f639190613ad2565b306000908152600660205260409020546004549192509080611f858584613b18565b611f8f9190613b37565b995080611f9c8484613b18565b611fa69190613b37565b985060008a118015611fb85750600089115b611fea5760405162461bcd60e51b815260206004820152600360248201526224a62160e91b60448201526064016106da565b611ff4308361324b565b611fff868c8c6129aa565b61200a858c8b6129aa565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a082319060240160206040518083038186803b15801561204957600080fd5b505afa15801561205d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120819190613ad2565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a082319060240160206040518083038186803b1580156120c357600080fd5b505afa1580156120d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fb9190613ad2565b925061210984848a8a612d3d565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050601b805460ff1916905550959794965093945050505050565b61218e60405180606001604052806000815260200160008152602001600081525090565b600d805461219e90600190613b01565b815481106121ae576121ae613bbc565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60028054610dba90613b59565b6000806122078585856001610ea8565b90506000805b825181101561224f5782818151811061222857612228613bbc565b60200260200101518261223b9190613ba4565b91508061224781613ef4565b91505061220d565b5061225a8482613b37565b9695505050505050565b6000612271338484613072565b50600192915050565b601b5460ff161561229d5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff19166001179055600954600a546010546040516370a0823160e01b81523060048201526001600160a01b03938416939092169161234a91849186919083906370a08231906024015b60206040518083038186803b15801561230357600080fd5b505afa158015612317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233b9190613ad2565b6123459190613b01565b6129aa565b6011546040516370a0823160e01b81523060048201526123829183918691906001600160a01b038416906370a08231906024016122eb565b5050601b805460ff1916905550565b60008061239d336132d6565b505033600090815260196020908152604080832054601a90925290912054811515806123c95750600081115b1561249757336000818152601960209081526040808320839055601a90915280822091909155600b54905163299e7ae760e11b8152600481019290925260248201849052604482018390526001600160a01b03169063533cf5ce90606401600060405180830381600087803b15801561244157600080fd5b505af1158015612455573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b428410156124db5760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b60448201526064016106da565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600160405161250b9190613f0f565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060078190556001600160a01b038a166000908152600890935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b9190876125d683613ef4565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161264f92919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156126ba573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906126f05750886001600160a01b0316816001600160a01b0316145b61273c5760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e415455524500000000000000000060448201526064016106da565b6001600160a01b038981166000818152600560209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b601054601154600c54600354604051632895a2f560e11b815260ff909116151560048201526000939291612710916001600160a01b039091169063512b45ea9060240160206040518083038186803b1580156127fe57600080fd5b505afa158015612812573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128369190613ad2565b6128409087613b18565b61284a9190613b37565b6128549086613b01565b945061286285858484612ed1565b95945050505050565b601b5460ff161561288e5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff191660011790556009546040516370a0823160e01b815230600482015261299e916001600160a01b0316906370a082319060240160206040518083038186803b1580156128e057600080fd5b505afa1580156128f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129189190613ad2565b600a546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561295b57600080fd5b505afa15801561296f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129939190613ad2565b601054601154612d3d565b601b805460ff19169055565b6000836001600160a01b03163b116129fa5760405162461bcd60e51b81526020600482015260136024820152722830b4b91d1034b73b30b634b2103a37b5b2b760691b60448201526064016106da565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612a569190613fab565b6000604051808303816000865af19150503d8060008114612a93576040519150601f19603f3d011682016040523d82523d6000602084013e612a98565b606091505b5091509150818015612ac2575080511580612ac2575080806020019051810190612ac29190613a6b565b612b065760405162461bcd60e51b815260206004820152601560248201527414185a5c8e881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016106da565b5050505050565b600954600b54612b2a916001600160a01b039081169116836129aa565b600454600090612b4283670de0b6b3a7640000613b18565b612b4c9190613b37565b90508015612b6c578060156000828254612b669190613ba4565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b600a54600b54612bc9916001600160a01b039081169116836129aa565b600454600090612be183670de0b6b3a7640000613b18565b612beb9190613b37565b90508015612c0b578060166000828254612c059190613ba4565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612ba0565b60035460009060ff1615612d2c57600e54600090612c6a85670de0b6b3a7640000613b18565b612c749190613b37565b90506000600f5484670de0b6b3a7640000612c8f9190613b18565b612c999190613b37565b90506000670de0b6b3a7640000612cb08385613b18565b612cba9190613b37565b90506000670de0b6b3a7640000612cd18480613b18565b612cdb9190613b37565b670de0b6b3a7640000612cee8680613b18565b612cf89190613b37565b612d029190613ba4565b9050670de0b6b3a7640000612d178284613b18565b612d219190613b37565b945050505050610ea2565b612d368284613b18565b9050610ea2565b6012544290600090612d4f9083613b01565b9050600081118015612d6057508315155b8015612d6b57508215155b15612db257612d7a8185613b18565b60136000828254612d8b9190613ba4565b90915550612d9b90508184613b18565b60146000828254612dac9190613ba4565b90915550505b6000612dbc61216a565b8051909150612dcb9084613b01565b9150610708821115612e80576040805160608101825284815260135460208201908152601454928201928352600d805460018101825560009190915291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5600390930292830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb682015590517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb7909101555b60108790556011869055601283905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60035460009060ff1615613022576000612eeb8484612c44565b600e54909150612f0385670de0b6b3a7640000613b18565b612f0d9190613b37565b600f54909450612f2584670de0b6b3a7640000613b18565b612f2f9190613b37565b60095490935060009081906001600160a01b03888116911614612f53578486612f56565b85855b60095491935091506001600160a01b03888116911614612f9457600f54612f8589670de0b6b3a7640000613b18565b612f8f9190613b37565b612fb3565b600e54612fa989670de0b6b3a7640000613b18565b612fb39190613b37565b97506000612fcb612fc4848b613ba4565b8584613436565b612fd59083613b01565b600954909150670de0b6b3a7640000906001600160a01b038a8116911614612fff57600e54613003565b600f545b61300d9083613b18565b6130179190613b37565b94505050505061109c565b60095460009081906001600160a01b03878116911614613043578385613046565b84845b90925090506130558783613ba4565b61305f8289613b18565b6130699190613b37565b9250505061109c565b61307b836132d6565b613084826132d6565b6001600160a01b038316600090815260066020526040812080548392906130ac908490613b01565b90915550506001600160a01b038216600090815260066020526040812080548392906130d9908490613ba4565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161312591815260200190565b60405180910390a3505050565b60006003821115613193575080600061314c600283613b37565b613157906001613ba4565b90505b8181101561318d579050806002816131728186613b37565b61317c9190613ba4565b6131869190613b37565b905061315a565b50919050565b811561319d575060015b919050565b6131ab826132d6565b80600460008282546131bd9190613ba4565b90915550506001600160a01b038216600090815260066020526040812080548392906131ea908490613ba4565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b600081831061324457816111d5565b5090919050565b613254826132d6565b80600460008282546132669190613b01565b90915550506001600160a01b03821660009081526006602052604081208054839290613293908490613b01565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001613229565b6001600160a01b0381166000908152600660205260409020548015613404576001600160a01b03821660009081526017602090815260408083208054601880855292852080546015546016549481905594909552829055936133388584613b01565b905060006133468584613b01565b905081156133a1576000670de0b6b3a7640000613363848a613b18565b61336d9190613b37565b6001600160a01b038a1660009081526019602052604081208054929350839290919061339a908490613ba4565b9091555050505b80156133fa576000670de0b6b3a76400006133bc838a613b18565b6133c69190613b37565b6001600160a01b038a166000908152601a60205260408120805492935083929091906133f3908490613ba4565b9091555050505b5050505050505050565b6015546001600160a01b0383166000908152601760209081526040808320939093556016546018909152919020555050565b6000805b60ff81101561353c578260006134508783613545565b9050858110156134a057600061346688876135e2565b6134708389613b01565b61348290670de0b6b3a7640000613b18565b61348c9190613b37565b90506134988187613ba4565b9550506134e2565b60006134ac88876135e2565b6134b68884613b01565b6134c890670de0b6b3a7640000613b18565b6134d29190613b37565b90506134de8187613b01565b9550505b8185111561350b5760016134f68387613b01565b11613506578493505050506111d5565b613527565b60016135178684613b01565b11613527578493505050506111d5565b5050808061353490613ef4565b91505061343a565b50909392505050565b6000670de0b6b3a76400008281858161355e8280613b18565b6135689190613b37565b6135729190613b18565b61357c9190613b37565b6135869190613b18565b6135909190613b37565b670de0b6b3a76400008084816135a68280613b18565b6135b09190613b37565b6135ba9190613b18565b6135c49190613b37565b6135ce9086613b18565b6135d89190613b37565b6111d59190613ba4565b6000670de0b6b3a764000083816135f98280613b18565b6136039190613b37565b61360d9190613b18565b6136179190613b37565b670de0b6b3a76400008061362b8580613b18565b6136359190613b37565b613640866003613b18565b6135ce9190613b18565b61050580613fc883390190565b82805461366390613b59565b90600052602060002090601f01602090048101928261368557600085556136cb565b82601f1061369e57805160ff19168380011785556136cb565b828001600101855582156136cb579182015b828111156136cb5782518255916020019190600101906136b0565b506136d79291506136db565b5090565b5b808211156136d757600081556001016136dc565b6001600160a01b0381168114611e2157600080fd5b60008060008060006080868803121561371d57600080fd5b85359450602086013593506040860135613736816136f0565b9250606086013567ffffffffffffffff8082111561375357600080fd5b818801915088601f83011261376757600080fd5b81358181111561377657600080fd5b89602082850101111561378857600080fd5b9699959850939650602001949392505050565b60005b838110156137b657818101518382015260200161379e565b838111156137c5576000848401525b50505050565b60208152600082518060208401526137ea81604085016020870161379b565b601f01601f19169190910160400192915050565b6000806040838503121561381157600080fd5b823561381c816136f0565b946020939093013593505050565b6000806000806080858703121561384057600080fd5b843561384b816136f0565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561389d57835183529284019291840191600101613881565b50909695505050505050565b6000602082840312156138bb57600080fd5b81356111d5816136f0565b6000806000606084860312156138db57600080fd5b83356138e6816136f0565b925060208401356138f6816136f0565b929592945050506040919091013590565b60006020828403121561391957600080fd5b5035919050565b60008060006060848603121561393557600080fd5b8335613940816136f0565b95602085013595506040909401359392505050565b60ff81168114611e2157600080fd5b600080600080600080600060e0888a03121561397f57600080fd5b873561398a816136f0565b9650602088013561399a816136f0565b9550604088013594506060880135935060808801356139b881613955565b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156139e857600080fd5b82356139f3816136f0565b91506020830135613a03816136f0565b809150509250929050565b60008060408385031215613a2157600080fd5b823591506020830135613a03816136f0565b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b8051801515811461319d57600080fd5b600060208284031215613a7d57600080fd5b6111d582613a5b565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215613ae457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613b1357613b13613aeb565b500390565b6000816000190483118215151615613b3257613b32613aeb565b500290565b600082613b5457634e487b7160e01b600052601260045260246000fd5b500490565b600181811c90821680613b6d57607f821691505b6020821081141561318d57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008219821115613bb757613bb7613aeb565b500190565b634e487b7160e01b600052603260045260246000fd5b600080600060608486031215613be757600080fd5b8351613bf2816136f0565b6020850151909350613c03816136f0565b9150613c1160408501613a5b565b90509250925092565b600060208284031215613c2c57600080fd5b815167ffffffffffffffff80821115613c4457600080fd5b818401915084601f830112613c5857600080fd5b815181811115613c6a57613c6a613b8e565b604051601f8201601f19908116603f01168101908382118183101715613c9257613c92613b8e565b81604052828152876020848701011115613cab57600080fd5b613cbc83602083016020880161379b565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b815260008351613cf181600f85016020880161379b565b602f60f81b600f918401918201528351613d1281601084016020880161379b565b01601001949350505050565b6473414d4d2d60d81b815260008351613d3e81600585016020880161379b565b602f60f81b6005918401918201528351613d5f81600684016020880161379b565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351613d9781601185016020880161379b565b602f60f81b6011918401918201528351613db881601284016020880161379b565b01601201949350505050565b6476414d4d2d60d81b815260008351613d3e81600585016020880161379b565b600060208284031215613df657600080fd5b81516111d581613955565b600181815b80851115613e3c578160001904821115613e2257613e22613aeb565b80851615613e2f57918102915b93841c9390800290613e06565b509250929050565b600082613e5357506001610ea2565b81613e6057506000610ea2565b8160018114613e765760028114613e8057613e9c565b6001915050610ea2565b60ff841115613e9157613e91613aeb565b50506001821b610ea2565b5060208310610133831016604e8410600b8410161715613ebf575081810a610ea2565b613ec98383613e01565b8060001904821115613edd57613edd613aeb565b029392505050565b60006111d560ff841683613e44565b6000600019821415613f0857613f08613aeb565b5060010190565b600080835481600182811c915080831680613f2b57607f831692505b6020808410821415613f4b57634e487b7160e01b86526022600452602486fd5b818015613f5f5760018114613f7057613f9d565b60ff19861689528489019650613f9d565b60008a81526020902060005b86811015613f955781548b820152908501908301613f7c565b505084890196505b509498975050505050505050565b60008251613fbd81846020870161379b565b919091019291505056fe608060405234801561001057600080fd5b506104e5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063485cc9551461003b578063533cf5ce14610050575b600080fd5b61004e6100493660046103e5565b610063565b005b61004e61005e366004610418565b6101be565b600054610100900460ff16158080156100835750600054600160ff909116105b8061009d5750303b15801561009d575060005460ff166001145b6101055760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610128576000805461ff0019166101001790555b6000805462010000330262010000600160b01b0319909116179055600180546001600160a01b038581166001600160a01b031992831617909255600280549285169290911691909117905580156101b9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000546201000090046001600160a01b0316331461021e5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79207061697220636f6e74726163742063616e2063616c6c000000000060448201526064016100fc565b811561023b5760015461023b906001600160a01b03168484610254565b80156101b9576002546101b9906001600160a01b031684835b6000836001600160a01b03163b116102ae5760405162461bcd60e51b815260206004820152601760248201527f50616972466565733a20696e76616c696420746f6b656e00000000000000000060448201526064016100fc565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161030a919061044b565b6000604051808303816000865af19150503d8060008114610347576040519150601f19603f3d011682016040523d82523d6000602084013e61034c565b606091505b50915091508180156103765750805115806103765750808060200190518101906103769190610486565b6103c25760405162461bcd60e51b815260206004820152601960248201527f50616972466565733a207472616e73666572206661696c65640000000000000060448201526064016100fc565b5050505050565b80356001600160a01b03811681146103e057600080fd5b919050565b600080604083850312156103f857600080fd5b610401836103c9565b915061040f602084016103c9565b90509250929050565b60008060006060848603121561042d57600080fd5b610436846103c9565b95602085013595506040909401359392505050565b6000825160005b8181101561046c5760208186018101518583015201610452565b8181111561047b576000828501525b509190910192915050565b60006020828403121561049857600080fd5b815180151581146104a857600080fd5b939250505056fea2646970667358221220f418eda26197df009488985cfee3fcd1f0ab7a2753b961a0e7e7f93a48dc6a9364736f6c63430008090033a2646970667358221220e6211848c01219b2b1b74a53c3ead789ccb2ff653ffb0edecc38482d0fd1b44c64736f6c63430008090033a26469706673582212209b55840b8233d336e14811b59252a6e23acbbfb38f7b9f8eaf5bef94c7fea09564736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806382dfdce4116100f9578063bc063e1a11610097578063e1f76b4411610071578063e1f76b44146103a9578063e5e31b13146103bc578063eb13c4cf146103df578063f94c53c71461041757600080fd5b8063bc063e1a1461037b578063bedb86fb14610383578063d0fb02031461039657600080fd5b80639aab9248116100d35780639aab92481461032e5780639fd0506d14610336578063a336252c14610350578063b187bd261461035857600080fd5b806382dfdce4146102f55780638a4fa0d2146103085780639a7165e41461031b57600080fd5b80634e24f35e11610166578063574f2ba311610140578063574f2ba3146102985780636652f0bf146102a05780636801cc30146102b35780638129fc1c146102ed57600080fd5b80634e24f35e1461025c5780635084ed031461027c578063512b45ea1461028557600080fd5b80632b724a28116101a25780632b724a28146102165780632d88af4a1461022d57806340bbd77514610240578063472d35b91461024957600080fd5b8063167a6f90146101c95780631e3dd18b146101d3578063269eec3a14610203575b600080fd5b6101d161041f565b005b6101e66101e1366004610e4c565b6104ab565b6040516001600160a01b0390911681526020015b60405180910390f35b6101d1610211366004610e81565b6104d5565b61021f600b5481565b6040519081526020016101fa565b6101d161023b366004610eab565b61059f565b61021f60025481565b6101d1610257366004610eab565b61061e565b61021f61026a366004610eab565b600c6020526000908152604090205481565b61021f60035481565b61021f610293366004610ed4565b61066a565b60075461021f565b61021f6102ae366004610eab565b6106dc565b6101e66102c1366004610ef1565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6101d161077e565b6101e6610303366004610ef1565b6108c8565b6005546101e6906001600160a01b031681565b6001546101e6906001600160a01b031681565b61021f610c04565b6000546101e690630100000090046001600160a01b031681565b6101d1610c36565b60005461036b9062010000900460ff1681565b60405190151581526020016101fa565b61021f601e81565b6101d1610391366004610ed4565b610c88565b6004546101e6906001600160a01b031681565b6101d16103b7366004610f38565b610d01565b61036b6103ca366004610eab565b60086020526000908152604090205460ff1681565b600954600a54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff161515908201526060016101fa565b6101d1610dc1565b6001546001600160a01b0316331461047e5760405162461bcd60e51b815260206004820181905260248201527f50616972466163746f72793a206e6f7420612070656e64696e6750617573657260448201526064015b60405180910390fd5b600154600080546301000000600160b81b0319166001600160a01b03909216630100000002919091179055565b600781815481106104bb57600080fd5b6000918252602090912001546001600160a01b0316905081565b6004546001600160a01b031633146104ff5760405162461bcd60e51b815260040161047590610f56565b600b548111156105405760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610475565b806105835760405162461bcd60e51b8152602060048201526013602482015272666565206d757374206265206e6f6e7a65726f60681b6044820152606401610475565b6001600160a01b039091166000908152600c6020526040902055565b600054630100000090046001600160a01b031633146105fc5760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b6044820152606401610475565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031633146106485760405162461bcd60e51b815260040161047590610f56565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b3360008181526008602052604081205490919060ff16156106c4576001600160a01b0381166000908152600c602052604090205480156106ab579392505050565b836106b8576003546106bc565b6002545b949350505050565b826106d1576003546106d5565b6002545b9392505050565b6001600160a01b0381166000908152600c602052604081205480156107015792915050565b826001600160a01b03166322be3de16040518163ffffffff1660e01b815260040160206040518083038186803b15801561073a57600080fd5b505afa15801561074e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107729190610f7f565b6106d1576003546106d5565b600054610100900460ff161580801561079e5750600054600160ff909116105b806107b85750303b1580156107b8575060005460ff166001145b61081b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610475565b6000805460ff19166001179055801561083e576000805461ff0019166101001790555b6000805462010000600160b81b031916336301000000810262ff0000191691909117909155600480546001600160a01b031916909117905560028055601460035580156108c5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000826001600160a01b0316846001600160a01b031614156109115760405162461bcd60e51b8152602060048201526002602482015261494160f01b6044820152606401610475565b600080846001600160a01b0316866001600160a01b031610610934578486610937565b85855b90925090506001600160a01b0382166109775760405162461bcd60e51b81526020600482015260026024820152615a4160f01b6044820152606401610475565b6001600160a01b03828116600090815260066020908152604080832085851684528252808320881515845290915290205416156109db5760405162461bcd60e51b8152602060048201526002602482015261504560f01b6044820152606401610475565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600a80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600980549288169290911691909117905591506000908290610a8390610e3f565b8190604051809103906000f5905080158015610aa3573d6000803e3d6000fd5b509050806001600160a01b0316638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ae157600080fd5b505af1158015610af5573d6000803e3d6000fd5b505050506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560078054600181810183557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889091018054909a1687179099558587526008855295839020805460ff19169098179097559354815196875291860192909252908401529296508692917fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a3505050509392505050565b600060405180602001610c1690610e3f565b6020820181038252601f19601f8201166040525080519060200120905090565b6004546001600160a01b03163314610c805760405162461bcd60e51b815260206004820152600d60248201526c5465616d204d53204f6e6c792160981b6044820152606401610475565b610539600b55565b600054630100000090046001600160a01b03163314610ce55760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b6044820152606401610475565b60008054911515620100000262ff000019909216919091179055565b6004546001600160a01b03163314610d2b5760405162461bcd60e51b815260040161047590610f56565b600b54811115610d6c5760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610475565b80610daf5760405162461bcd60e51b8152602060048201526013602482015272666565206d757374206265206e6f6e7a65726f60681b6044820152606401610475565b8115610dbb5760025550565b60035550565b6005546001600160a01b03163314610e1b5760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e616765720000000000000000006044820152606401610475565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b61452280610f9d83390190565b600060208284031215610e5e57600080fd5b5035919050565b80356001600160a01b0381168114610e7c57600080fd5b919050565b60008060408385031215610e9457600080fd5b610e9d83610e65565b946020939093013593505050565b600060208284031215610ebd57600080fd5b6106d582610e65565b80151581146108c557600080fd5b600060208284031215610ee657600080fd5b81356106d581610ec6565b600080600060608486031215610f0657600080fd5b610f0f84610e65565b9250610f1d60208501610e65565b91506040840135610f2d81610ec6565b809150509250925092565b60008060408385031215610f4b57600080fd5b8235610e9d81610ec6565b6020808252600f908201526e3737ba103332b29036b0b730b3b2b960891b604082015260600190565b600060208284031215610f9157600080fd5b81516106d581610ec656fe608060405234801561001057600080fd5b50614502806100206000396000f3fe608060405234801561001057600080fd5b506004361061028a5760003560e01c80638129fc1c1161015c578063bda39cad116100ce578063d294f09311610087578063d294f0931461064e578063d505accf14610656578063dd62ed3e14610669578063ebeb31db14610694578063f140a35a1461069c578063fff6cae9146106af57600080fd5b8063bda39cad14610604578063bf944dbc1461060d578063c245febc14610616578063c45a01551461061f578063c5700a0214610632578063d21220a71461063b57600080fd5b80639d63848a116101205780639d63848a146105655780639e8cc04b1461058b5780639f767c881461059e578063a1ac4d13146105be578063a9059cbb146105de578063bc25cf77146105f157600080fd5b80638129fc1c146104f057806389afcb44146104f85780638a7b8cf21461052057806395d89b411461054a5780639af1d35a1461055257600080fd5b8063252c09d711610200578063517b3f82116101b9578063517b3f821461046e5780635881c475146104815780635a76f25e146104945780636a6278421461049d57806370a08231146104b05780637ecebe00146104d057600080fd5b8063252c09d7146103b4578063313ce567146103c757806332c0defd146103e1578063392f37e9146103ea578063443cb4bc146104455780634d5a9f8a1461044e57600080fd5b806313345fe11161025257806313345fe11461033557806318160ddd146103555780631df8c7171461036c578063205aabf11461037457806322be3de11461039457806323b872dd146103a157600080fd5b8063022c0d9f1461028f57806306fdde03146102a45780630902f1ac146102c2578063095ea7b3146102e75780630dfe16811461030a575b600080fd5b6102a261029d366004613705565b6106b7565b005b6102ac610dad565b6040516102b991906137cb565b60405180910390f35b6010546011546012545b604080519384526020840192909252908201526060016102b9565b6102fa6102f53660046137fe565b610e3b565b60405190151581526020016102b9565b60095461031d906001600160a01b031681565b6040516001600160a01b0390911681526020016102b9565b61034861034336600461382a565b610ea8565b6040516102b99190613865565b61035e60045481565b6040519081526020016102b9565b6102cc6110a4565b61035e6103823660046138a9565b60186020526000908152604090205481565b6003546102fa9060ff1681565b6102fa6103af3660046138c6565b611113565b6102cc6103c2366004613907565b6111dc565b6103cf601281565b60405160ff90911681526020016102b9565b61035e60155481565b600e54600f54601054601154600354600954600a5460408051978852602088019690965294860193909352606085019190915260ff16151560808401526001600160a01b0390811660a08401521660c082015260e0016102b9565b61035e60105481565b61035e61045c3660046138a9565b60196020526000908152604090205481565b61035e61047c3660046137fe565b61120f565b61034861048f366004613920565b6112f8565b61035e60115481565b61035e6104ab3660046138a9565b611307565b61035e6104be3660046138a9565b60066020526000908152604090205481565b61035e6104de3660046138a9565b60086020526000908152604090205481565b6102a261156a565b61050b6105063660046138a9565b611e24565b604080519283526020830191909152016102b9565b61052861216a565b60408051825181526020808401519082015291810151908201526060016102b9565b6102ac6121ea565b600b5461031d906001600160a01b031681565b600954600a54604080516001600160a01b039384168152929091166020830152016102b9565b61035e610599366004613920565b6121f7565b61035e6105ac3660046138a9565b60176020526000908152604090205481565b61035e6105cc3660046138a9565b601a6020526000908152604090205481565b6102fa6105ec3660046137fe565b612264565b6102a26105ff3660046138a9565b61227a565b61035e60165481565b61035e60135481565b61035e60145481565b600c5461031d906001600160a01b031681565b61035e60125481565b600a5461031d906001600160a01b031681565b61050b612391565b6102a2610664366004613964565b61249b565b61035e6106773660046139d5565b600560209081526000928352604080842090915290825290205481565b600d5461035e565b61035e6106aa366004613a0e565b6127a3565b6102a261286b565b601b5460ff16156106e35760405162461bcd60e51b81526004016106da90613a33565b60405180910390fd5b601b805460ff19166001179055600c54604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561073557600080fd5b505afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190613a6b565b1561077757600080fd5b60008511806107865750600084115b6107b85760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064016106da565b60105460115481871080156107cc57508086105b6107fd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b60448201526064016106da565b600954600a5460009182916001600160a01b0391821691908116908916821480159061083b5750806001600160a01b0316896001600160a01b031614155b61086c5760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106da565b8a1561087d5761087d828a8d6129aa565b891561088e5761088e818a8c6129aa565b86156108fb57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906108c89033908f908f908e908e90600401613a86565b600060405180830381600087803b1580156108e257600080fd5b505af11580156108f6573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109729190613ad2565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a082319060240160206040518083038186803b1580156109b457600080fd5b505afa1580156109c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ec9190613ad2565b92505050600089856109fe9190613b01565b8311610a0b576000610a1f565b610a158a86613b01565b610a1f9084613b01565b90506000610a2d8a86613b01565b8311610a3a576000610a4e565b610a448a86613b01565b610a4e9084613b01565b90506000821180610a5f5750600081115b610a915760405162461bcd60e51b815260206004820152600360248201526249494160e81b60448201526064016106da565b600954600a546001600160a01b0391821691168315610b4f57600c54600354604051632895a2f560e11b815260ff90911615156004820152610b4f91612710916001600160a01b039091169063512b45ea9060240160206040518083038186803b158015610afe57600080fd5b505afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190613ad2565b610b409087613b18565b610b4a9190613b37565b612b0d565b8215610bfa57600c54600354604051632895a2f560e11b815260ff90911615156004820152610bfa91612710916001600160a01b039091169063512b45ea9060240160206040518083038186803b158015610ba957600080fd5b505afa158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190613ad2565b610beb9086613b18565b610bf59190613b37565b612bac565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015610c3957600080fd5b505afa158015610c4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c719190613ad2565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a082319060240160206040518083038186803b158015610cb357600080fd5b505afa158015610cc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ceb9190613ad2565b9450610cf78888612c44565b610d018787612c44565b1015610d335760405162461bcd60e51b81526020600482015260016024820152604b60f81b60448201526064016106da565b5050610d4184848888612d3d565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a35050601b805460ff19169055505050505050505050565b60018054610dba90613b59565b80601f0160208091040260200160405190810160405280929190818152602001828054610de690613b59565b8015610e335780601f10610e0857610100808354040283529160200191610e33565b820191906000526020600020905b815481529060010190602001808311610e1657829003601f168201915b505050505081565b3360008181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610e969086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115610ec557610ec5613b8e565b604051908082528060200260200182016040528015610eee578160200160208202803683370190505b50600d54909150600090610f0490600190613b01565b90506000610f128587613b18565b610f1c9083613b01565b90506000805b8383101561109457610f348784613ba4565b91506000600d8481548110610f4b57610f4b613bbc565b906000526020600020906003020160000154600d8481548110610f7057610f70613bbc565b906000526020600020906003020160000154610f8c9190613b01565b9050600081600d8681548110610fa457610fa4613bbc565b906000526020600020906003020160010154600d8681548110610fc957610fc9613bbc565b906000526020600020906003020160010154610fe59190613b01565b610fef9190613b37565b9050600082600d878154811061100757611007613bbc565b906000526020600020906003020160020154600d878154811061102c5761102c613bbc565b9060005260206000209060030201600201546110489190613b01565b6110529190613b37565b90506110608c8e8484612ed1565b88858151811061107257611072613bbc565b602090810291909101015250505060010161108d8784613ba4565b9250610f22565b509293505050505b949350505050565b60135460145442600080806110c26010546011546012549192909190565b92509250925083811461110b5760006110db8286613b01565b90506110e78185613b18565b6110f19088613ba4565b96506110fd8184613b18565b6111079087613ba4565b9550505b505050909192565b6001600160a01b03831660008181526005602090815260408083203380855292528220549192909190821480159061114d57506000198114155b156111c357600061115e8583613b01565b6001600160a01b038881166000818152600560209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6111ce868686613072565b6001925050505b9392505050565b600d81815481106111ec57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b60008061121a61216a565b90506000806112276110a4565b508451919350915042141561129057600d805461124690600290613b01565b8154811061125657611256613bbc565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b825160009061129f9042613b01565b90506000818560200151856112b49190613b01565b6112be9190613b37565b90506000828660400151856112d39190613b01565b6112dd9190613b37565b90506112eb888a8484612ed1565b9998505050505050505050565b606061109c8484846001610ea8565b601b5460009060ff161561132d5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff191660011790556010546011546009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561138457600080fd5b505afa158015611398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bc9190613ad2565b600a546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b15801561140557600080fd5b505afa158015611419573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143d9190613ad2565b9050600061144b8584613b01565b905060006114598584613b01565b60045490915080611497576103e86114796114748486613b18565b613132565b6114839190613b01565b975061149260006103e86131a2565b6114cc565b6114c9876114a58386613b18565b6114af9190613b37565b876114ba8486613b18565b6114c49190613b37565b613235565b97505b600088116115025760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b60448201526064016106da565b61150c89896131a2565b61151885858989612d3d565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25050601b805460ff19169055509395945050505050565b600054610100900460ff161580801561158a5750600054600160ff909116105b806115a45750303b1580156115a4575060005460ff166001145b6116075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106da565b6000805460ff19166001179055801561162a576000805461ff0019166101001790555b600c80546001600160a01b031916339081179091556040805163eb13c4cf60e01b815290516000928392839263eb13c4cf91600480820192606092909190829003018186803b15801561167c57600080fd5b505afa158015611690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b49190613bd2565b6003805482151560ff19909116179055600a80546001600160a01b038085166001600160a01b0319928316179092556009805492861692909116919091179055604051929550909350915060009061170b9061364a565b604051809103906000f080158015611727573d6000803e3d6000fd5b5060405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529192509082169063485cc95590604401600060405180830381600087803b15801561177757600080fd5b505af115801561178b573d6000803e3d6000fd5b5050600b80546001600160a01b0319166001600160a01b038516179055505081156119f557836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e957600080fd5b505afa1580156117fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118259190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561185e57600080fd5b505afa158015611872573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261189a9190810190613c1a565b6040516020016118ab929190613cc7565b604051602081830303815290604052600190805190602001906118cf929190613657565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561190957600080fd5b505afa15801561191d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119459190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561197e57600080fd5b505afa158015611992573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119ba9190810190613c1a565b6040516020016119cb929190613d1e565b604051602081830303815290604052600290805190602001906119ef929190613657565b50611c36565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611a2e57600080fd5b505afa158015611a42573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a6a9190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611aa357600080fd5b505afa158015611ab7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611adf9190810190613c1a565b604051602001611af0929190613d6b565b60405160208183030381529060405260019080519060200190611b14929190613657565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b4e57600080fd5b505afa158015611b62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b8a9190810190613c1a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bc357600080fd5b505afa158015611bd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bff9190810190613c1a565b604051602001611c10929190613dc4565b60405160208183030381529060405260029080519060200190611c34929190613657565b505b836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611c6f57600080fd5b505afa158015611c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca79190613de4565b611cb290600a613ee5565b600e81905550826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611cf157600080fd5b505afa158015611d05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d299190613de4565b611d3490600a613ee5565b600f55505060408051606081018252428152600060208201818152928201818152600d8054600181018255925291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb560039092029182015591517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb6830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb79091015550508015611e21576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b601b54600090819060ff1615611e4c5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff19166001179055601054601154600954600a546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a082319060240160206040518083038186803b158015611eae57600080fd5b505afa158015611ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee69190613ad2565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015611f2b57600080fd5b505afa158015611f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f639190613ad2565b306000908152600660205260409020546004549192509080611f858584613b18565b611f8f9190613b37565b995080611f9c8484613b18565b611fa69190613b37565b985060008a118015611fb85750600089115b611fea5760405162461bcd60e51b815260206004820152600360248201526224a62160e91b60448201526064016106da565b611ff4308361324b565b611fff868c8c6129aa565b61200a858c8b6129aa565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a082319060240160206040518083038186803b15801561204957600080fd5b505afa15801561205d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120819190613ad2565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a082319060240160206040518083038186803b1580156120c357600080fd5b505afa1580156120d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fb9190613ad2565b925061210984848a8a612d3d565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050601b805460ff1916905550959794965093945050505050565b61218e60405180606001604052806000815260200160008152602001600081525090565b600d805461219e90600190613b01565b815481106121ae576121ae613bbc565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60028054610dba90613b59565b6000806122078585856001610ea8565b90506000805b825181101561224f5782818151811061222857612228613bbc565b60200260200101518261223b9190613ba4565b91508061224781613ef4565b91505061220d565b5061225a8482613b37565b9695505050505050565b6000612271338484613072565b50600192915050565b601b5460ff161561229d5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff19166001179055600954600a546010546040516370a0823160e01b81523060048201526001600160a01b03938416939092169161234a91849186919083906370a08231906024015b60206040518083038186803b15801561230357600080fd5b505afa158015612317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233b9190613ad2565b6123459190613b01565b6129aa565b6011546040516370a0823160e01b81523060048201526123829183918691906001600160a01b038416906370a08231906024016122eb565b5050601b805460ff1916905550565b60008061239d336132d6565b505033600090815260196020908152604080832054601a90925290912054811515806123c95750600081115b1561249757336000818152601960209081526040808320839055601a90915280822091909155600b54905163299e7ae760e11b8152600481019290925260248201849052604482018390526001600160a01b03169063533cf5ce90606401600060405180830381600087803b15801561244157600080fd5b505af1158015612455573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b428410156124db5760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b60448201526064016106da565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600160405161250b9190613f0f565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060078190556001600160a01b038a166000908152600890935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b9190876125d683613ef4565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161264f92919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156126ba573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906126f05750886001600160a01b0316816001600160a01b0316145b61273c5760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e415455524500000000000000000060448201526064016106da565b6001600160a01b038981166000818152600560209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b601054601154600c54600354604051632895a2f560e11b815260ff909116151560048201526000939291612710916001600160a01b039091169063512b45ea9060240160206040518083038186803b1580156127fe57600080fd5b505afa158015612812573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128369190613ad2565b6128409087613b18565b61284a9190613b37565b6128549086613b01565b945061286285858484612ed1565b95945050505050565b601b5460ff161561288e5760405162461bcd60e51b81526004016106da90613a33565b601b805460ff191660011790556009546040516370a0823160e01b815230600482015261299e916001600160a01b0316906370a082319060240160206040518083038186803b1580156128e057600080fd5b505afa1580156128f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129189190613ad2565b600a546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561295b57600080fd5b505afa15801561296f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129939190613ad2565b601054601154612d3d565b601b805460ff19169055565b6000836001600160a01b03163b116129fa5760405162461bcd60e51b81526020600482015260136024820152722830b4b91d1034b73b30b634b2103a37b5b2b760691b60448201526064016106da565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612a569190613fab565b6000604051808303816000865af19150503d8060008114612a93576040519150601f19603f3d011682016040523d82523d6000602084013e612a98565b606091505b5091509150818015612ac2575080511580612ac2575080806020019051810190612ac29190613a6b565b612b065760405162461bcd60e51b815260206004820152601560248201527414185a5c8e881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016106da565b5050505050565b600954600b54612b2a916001600160a01b039081169116836129aa565b600454600090612b4283670de0b6b3a7640000613b18565b612b4c9190613b37565b90508015612b6c578060156000828254612b669190613ba4565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b600a54600b54612bc9916001600160a01b039081169116836129aa565b600454600090612be183670de0b6b3a7640000613b18565b612beb9190613b37565b90508015612c0b578060166000828254612c059190613ba4565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612ba0565b60035460009060ff1615612d2c57600e54600090612c6a85670de0b6b3a7640000613b18565b612c749190613b37565b90506000600f5484670de0b6b3a7640000612c8f9190613b18565b612c999190613b37565b90506000670de0b6b3a7640000612cb08385613b18565b612cba9190613b37565b90506000670de0b6b3a7640000612cd18480613b18565b612cdb9190613b37565b670de0b6b3a7640000612cee8680613b18565b612cf89190613b37565b612d029190613ba4565b9050670de0b6b3a7640000612d178284613b18565b612d219190613b37565b945050505050610ea2565b612d368284613b18565b9050610ea2565b6012544290600090612d4f9083613b01565b9050600081118015612d6057508315155b8015612d6b57508215155b15612db257612d7a8185613b18565b60136000828254612d8b9190613ba4565b90915550612d9b90508184613b18565b60146000828254612dac9190613ba4565b90915550505b6000612dbc61216a565b8051909150612dcb9084613b01565b9150610708821115612e80576040805160608101825284815260135460208201908152601454928201928352600d805460018101825560009190915291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5600390930292830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb682015590517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb7909101555b60108790556011869055601283905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60035460009060ff1615613022576000612eeb8484612c44565b600e54909150612f0385670de0b6b3a7640000613b18565b612f0d9190613b37565b600f54909450612f2584670de0b6b3a7640000613b18565b612f2f9190613b37565b60095490935060009081906001600160a01b03888116911614612f53578486612f56565b85855b60095491935091506001600160a01b03888116911614612f9457600f54612f8589670de0b6b3a7640000613b18565b612f8f9190613b37565b612fb3565b600e54612fa989670de0b6b3a7640000613b18565b612fb39190613b37565b97506000612fcb612fc4848b613ba4565b8584613436565b612fd59083613b01565b600954909150670de0b6b3a7640000906001600160a01b038a8116911614612fff57600e54613003565b600f545b61300d9083613b18565b6130179190613b37565b94505050505061109c565b60095460009081906001600160a01b03878116911614613043578385613046565b84845b90925090506130558783613ba4565b61305f8289613b18565b6130699190613b37565b9250505061109c565b61307b836132d6565b613084826132d6565b6001600160a01b038316600090815260066020526040812080548392906130ac908490613b01565b90915550506001600160a01b038216600090815260066020526040812080548392906130d9908490613ba4565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161312591815260200190565b60405180910390a3505050565b60006003821115613193575080600061314c600283613b37565b613157906001613ba4565b90505b8181101561318d579050806002816131728186613b37565b61317c9190613ba4565b6131869190613b37565b905061315a565b50919050565b811561319d575060015b919050565b6131ab826132d6565b80600460008282546131bd9190613ba4565b90915550506001600160a01b038216600090815260066020526040812080548392906131ea908490613ba4565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b600081831061324457816111d5565b5090919050565b613254826132d6565b80600460008282546132669190613b01565b90915550506001600160a01b03821660009081526006602052604081208054839290613293908490613b01565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001613229565b6001600160a01b0381166000908152600660205260409020548015613404576001600160a01b03821660009081526017602090815260408083208054601880855292852080546015546016549481905594909552829055936133388584613b01565b905060006133468584613b01565b905081156133a1576000670de0b6b3a7640000613363848a613b18565b61336d9190613b37565b6001600160a01b038a1660009081526019602052604081208054929350839290919061339a908490613ba4565b9091555050505b80156133fa576000670de0b6b3a76400006133bc838a613b18565b6133c69190613b37565b6001600160a01b038a166000908152601a60205260408120805492935083929091906133f3908490613ba4565b9091555050505b5050505050505050565b6015546001600160a01b0383166000908152601760209081526040808320939093556016546018909152919020555050565b6000805b60ff81101561353c578260006134508783613545565b9050858110156134a057600061346688876135e2565b6134708389613b01565b61348290670de0b6b3a7640000613b18565b61348c9190613b37565b90506134988187613ba4565b9550506134e2565b60006134ac88876135e2565b6134b68884613b01565b6134c890670de0b6b3a7640000613b18565b6134d29190613b37565b90506134de8187613b01565b9550505b8185111561350b5760016134f68387613b01565b11613506578493505050506111d5565b613527565b60016135178684613b01565b11613527578493505050506111d5565b5050808061353490613ef4565b91505061343a565b50909392505050565b6000670de0b6b3a76400008281858161355e8280613b18565b6135689190613b37565b6135729190613b18565b61357c9190613b37565b6135869190613b18565b6135909190613b37565b670de0b6b3a76400008084816135a68280613b18565b6135b09190613b37565b6135ba9190613b18565b6135c49190613b37565b6135ce9086613b18565b6135d89190613b37565b6111d59190613ba4565b6000670de0b6b3a764000083816135f98280613b18565b6136039190613b37565b61360d9190613b18565b6136179190613b37565b670de0b6b3a76400008061362b8580613b18565b6136359190613b37565b613640866003613b18565b6135ce9190613b18565b61050580613fc883390190565b82805461366390613b59565b90600052602060002090601f01602090048101928261368557600085556136cb565b82601f1061369e57805160ff19168380011785556136cb565b828001600101855582156136cb579182015b828111156136cb5782518255916020019190600101906136b0565b506136d79291506136db565b5090565b5b808211156136d757600081556001016136dc565b6001600160a01b0381168114611e2157600080fd5b60008060008060006080868803121561371d57600080fd5b85359450602086013593506040860135613736816136f0565b9250606086013567ffffffffffffffff8082111561375357600080fd5b818801915088601f83011261376757600080fd5b81358181111561377657600080fd5b89602082850101111561378857600080fd5b9699959850939650602001949392505050565b60005b838110156137b657818101518382015260200161379e565b838111156137c5576000848401525b50505050565b60208152600082518060208401526137ea81604085016020870161379b565b601f01601f19169190910160400192915050565b6000806040838503121561381157600080fd5b823561381c816136f0565b946020939093013593505050565b6000806000806080858703121561384057600080fd5b843561384b816136f0565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561389d57835183529284019291840191600101613881565b50909695505050505050565b6000602082840312156138bb57600080fd5b81356111d5816136f0565b6000806000606084860312156138db57600080fd5b83356138e6816136f0565b925060208401356138f6816136f0565b929592945050506040919091013590565b60006020828403121561391957600080fd5b5035919050565b60008060006060848603121561393557600080fd5b8335613940816136f0565b95602085013595506040909401359392505050565b60ff81168114611e2157600080fd5b600080600080600080600060e0888a03121561397f57600080fd5b873561398a816136f0565b9650602088013561399a816136f0565b9550604088013594506060880135935060808801356139b881613955565b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156139e857600080fd5b82356139f3816136f0565b91506020830135613a03816136f0565b809150509250929050565b60008060408385031215613a2157600080fd5b823591506020830135613a03816136f0565b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b8051801515811461319d57600080fd5b600060208284031215613a7d57600080fd5b6111d582613a5b565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215613ae457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613b1357613b13613aeb565b500390565b6000816000190483118215151615613b3257613b32613aeb565b500290565b600082613b5457634e487b7160e01b600052601260045260246000fd5b500490565b600181811c90821680613b6d57607f821691505b6020821081141561318d57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008219821115613bb757613bb7613aeb565b500190565b634e487b7160e01b600052603260045260246000fd5b600080600060608486031215613be757600080fd5b8351613bf2816136f0565b6020850151909350613c03816136f0565b9150613c1160408501613a5b565b90509250925092565b600060208284031215613c2c57600080fd5b815167ffffffffffffffff80821115613c4457600080fd5b818401915084601f830112613c5857600080fd5b815181811115613c6a57613c6a613b8e565b604051601f8201601f19908116603f01168101908382118183101715613c9257613c92613b8e565b81604052828152876020848701011115613cab57600080fd5b613cbc83602083016020880161379b565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b815260008351613cf181600f85016020880161379b565b602f60f81b600f918401918201528351613d1281601084016020880161379b565b01601001949350505050565b6473414d4d2d60d81b815260008351613d3e81600585016020880161379b565b602f60f81b6005918401918201528351613d5f81600684016020880161379b565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351613d9781601185016020880161379b565b602f60f81b6011918401918201528351613db881601284016020880161379b565b01601201949350505050565b6476414d4d2d60d81b815260008351613d3e81600585016020880161379b565b600060208284031215613df657600080fd5b81516111d581613955565b600181815b80851115613e3c578160001904821115613e2257613e22613aeb565b80851615613e2f57918102915b93841c9390800290613e06565b509250929050565b600082613e5357506001610ea2565b81613e6057506000610ea2565b8160018114613e765760028114613e8057613e9c565b6001915050610ea2565b60ff841115613e9157613e91613aeb565b50506001821b610ea2565b5060208310610133831016604e8410600b8410161715613ebf575081810a610ea2565b613ec98383613e01565b8060001904821115613edd57613edd613aeb565b029392505050565b60006111d560ff841683613e44565b6000600019821415613f0857613f08613aeb565b5060010190565b600080835481600182811c915080831680613f2b57607f831692505b6020808410821415613f4b57634e487b7160e01b86526022600452602486fd5b818015613f5f5760018114613f7057613f9d565b60ff19861689528489019650613f9d565b60008a81526020902060005b86811015613f955781548b820152908501908301613f7c565b505084890196505b509498975050505050505050565b60008251613fbd81846020870161379b565b919091019291505056fe608060405234801561001057600080fd5b506104e5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063485cc9551461003b578063533cf5ce14610050575b600080fd5b61004e6100493660046103e5565b610063565b005b61004e61005e366004610418565b6101be565b600054610100900460ff16158080156100835750600054600160ff909116105b8061009d5750303b15801561009d575060005460ff166001145b6101055760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610128576000805461ff0019166101001790555b6000805462010000330262010000600160b01b0319909116179055600180546001600160a01b038581166001600160a01b031992831617909255600280549285169290911691909117905580156101b9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000546201000090046001600160a01b0316331461021e5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79207061697220636f6e74726163742063616e2063616c6c000000000060448201526064016100fc565b811561023b5760015461023b906001600160a01b03168484610254565b80156101b9576002546101b9906001600160a01b031684835b6000836001600160a01b03163b116102ae5760405162461bcd60e51b815260206004820152601760248201527f50616972466565733a20696e76616c696420746f6b656e00000000000000000060448201526064016100fc565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161030a919061044b565b6000604051808303816000865af19150503d8060008114610347576040519150601f19603f3d011682016040523d82523d6000602084013e61034c565b606091505b50915091508180156103765750805115806103765750808060200190518101906103769190610486565b6103c25760405162461bcd60e51b815260206004820152601960248201527f50616972466565733a207472616e73666572206661696c65640000000000000060448201526064016100fc565b5050505050565b80356001600160a01b03811681146103e057600080fd5b919050565b600080604083850312156103f857600080fd5b610401836103c9565b915061040f602084016103c9565b90509250929050565b60008060006060848603121561042d57600080fd5b610436846103c9565b95602085013595506040909401359392505050565b6000825160005b8181101561046c5760208186018101518583015201610452565b8181111561047b576000828501525b509190910192915050565b60006020828403121561049857600080fd5b815180151581146104a857600080fd5b939250505056fea2646970667358221220f418eda26197df009488985cfee3fcd1f0ab7a2753b961a0e7e7f93a48dc6a9364736f6c63430008090033a2646970667358221220e6211848c01219b2b1b74a53c3ead789ccb2ff653ffb0edecc38482d0fd1b44c64736f6c63430008090033a26469706673582212209b55840b8233d336e14811b59252a6e23acbbfb38f7b9f8eaf5bef94c7fea09564736f6c63430008090033
Deployed Bytecode Sourcemap
42426:6422:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44742:157;;;:::i;:::-;;42839:25;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;363:32:1;;;345:51;;333:2;318:18;42839:25:0;;;;;;;;45762:280;;;;;;:::i;:::-;;:::i;43498:33::-;;;;;;;;;990:25:1;;;978:2;963:18;43498:33:0;844:177:1;44578:156:0;;;;;;:::i;:::-;;:::i;42565:24::-;;;;;;45060:166;;;;;;:::i;:::-;;:::i;43548:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;42596:26;;;;;;46369:817;;;;;;:::i;:::-;;:::i;44474:96::-;44547:8;:15;44474:96;;46050:311;;;;;;:::i;:::-;;:::i;42753:79::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;42753:79:0;;;44258:208;;;:::i;47645:1044::-;;;;;;:::i;:::-;;:::i;42712:32::-;;;;;-1:-1:-1;;;;;42712:32:0;;;42528:28;;;;;-1:-1:-1;;;;;42528:28:0;;;47389:116;;;:::i;42500:21::-;;;;;;;;-1:-1:-1;;;;;42500:21:0;;;48697:148;;;:::i;42473:20::-;;;;;;;;;;;;;;;2327:14:1;;2320:22;2302:41;;2290:2;2275:18;42473:20:0;2162:187:1;42629:36:0;;42663:2;42629:36;;44907:145;;;;;;:::i;:::-;;:::i;42680:25::-;;;;;-1:-1:-1;;;;;42680:25:0;;;45406:348;;;;;;:::i;:::-;;:::i;42871:38::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;47513:124;47607:6;;47615;;47513:124;;;-1:-1:-1;;;;;47607:6:0;;;2902:34:1;;47615:6:0;;;2967:2:1;2952:18;;2945:43;-1:-1:-1;;;47623:5:0;;;;;3031:14:1;3024:22;3004:18;;;2997:50;2852:2;2837:18;47513:124:0;2668:385:1;45234:164:0;;;:::i;44742:157::-;44808:13;;-1:-1:-1;;;;;44808:13:0;44794:10;:27;44786:72;;;;-1:-1:-1;;;44786:72:0;;3260:2:1;44786:72:0;;;3242:21:1;;;3279:18;;;3272:30;3338:34;3318:18;;;3311:62;3390:18;;44786:72:0;;;;;;;;;44878:13;;;44869:22;;-1:-1:-1;;;;;;44869:22:0;-1:-1:-1;;;;;44878:13:0;;;44869:22;;;;;;;;44742:157::o;42839:25::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;42839:25:0;;-1:-1:-1;42839:25:0;:::o;45762:280::-;45859:10;;-1:-1:-1;;;;;45859:10:0;45845;:24;45837:52;;;;-1:-1:-1;;;45837:52:0;;;;;;;:::i;:::-;45916:11;;45908:4;:19;;45900:44;;;;-1:-1:-1;;;45900:44:0;;3965:2:1;45900:44:0;;;3947:21:1;4004:2;3984:18;;;3977:30;-1:-1:-1;;;4023:18:1;;;4016:42;4075:18;;45900:44:0;3763:336:1;45900:44:0;45963:9;45955:41;;;;-1:-1:-1;;;45955:41:0;;4306:2:1;45955:41:0;;;4288:21:1;4345:2;4325:18;;;4318:30;-1:-1:-1;;;4364:18:1;;;4357:49;4423:18;;45955:41:0;4104:343:1;45955:41:0;-1:-1:-1;;;;;46007:20:0;;;;;;;:13;:20;;;;;:27;45762:280::o;44578:156::-;44656:6;;;;;-1:-1:-1;;;;;44656:6:0;44642:10;:20;44634:58;;;;-1:-1:-1;;;44634:58:0;;4654:2:1;44634:58:0;;;4636:21:1;4693:2;4673:18;;;4666:30;-1:-1:-1;;;4712:18:1;;;4705:55;4777:18;;44634:58:0;4452:349:1;44634:58:0;44703:13;:23;;-1:-1:-1;;;;;;44703:23:0;-1:-1:-1;;;;;44703:23:0;;;;;;;;;;44578:156::o;45060:166::-;45146:10;;-1:-1:-1;;;;;45146:10:0;45132;:24;45124:52;;;;-1:-1:-1;;;45124:52:0;;;;;;;:::i;:::-;45187:17;:31;;-1:-1:-1;;;;;;45187:31:0;-1:-1:-1;;;;;45187:31:0;;;;;;;;;;45060:166::o;46369:817::-;46862:10;46419:7;46883:12;;;:6;:12;;;;;;46419:7;;46862:10;46883:12;;46880:260;;;-1:-1:-1;;;;;46917:19:0;;46906:8;46917:19;;;:13;:19;;;;;;46949:7;;46945:97;;46976:3;46369:817;-1:-1:-1;;;46369:817:0:o;46945:97::-;47009:7;:33;;47031:11;;47009:33;;;47019:9;;47009:33;47002:40;46369:817;-1:-1:-1;;;;46369:817:0:o;46880:260::-;47107:7;:33;;47129:11;;47107:33;;;47117:9;;47107:33;47100:40;46369:817;-1:-1:-1;;;46369:817:0:o;46050:311::-;-1:-1:-1;;;;;46199:22:0;;46105:7;46199:22;;;:13;:22;;;;;;46233:7;;46229:125;;46259:3;46050:311;-1:-1:-1;;46050:311:0:o;46229:125::-;46304:5;-1:-1:-1;;;;;46298:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;46334:11;;46298:47;;44258:208;14302:19;14325:13;;;;;;14324:14;;14372:34;;;;-1:-1:-1;14390:12:0;;14405:1;14390:12;;;;:16;14372:34;14371:108;;;-1:-1:-1;14451:4:0;5064:19;:23;;;14412:66;;-1:-1:-1;14461:12:0;;;;;:17;14412:66;14349:204;;;;-1:-1:-1;;;14349:204:0;;5258:2:1;14349:204:0;;;5240:21:1;5297:2;5277:18;;;5270:30;5336:34;5316:18;;;5309:62;-1:-1:-1;;;5387:18:1;;;5380:44;5441:19;;14349:204:0;5056:410:1;14349:204:0;14564:12;:16;;-1:-1:-1;;14564:16:0;14579:1;14564:16;;;14591:67;;;;14626:13;:20;;-1:-1:-1;;14626:20:0;;;;;14591:67;44310:6:::1;:19:::0;;-1:-1:-1;;;;;;44340:16:0;44319:10:::1;44310:19:::0;;::::1;-1:-1:-1::0;;44340:16:0;;;;;;;;44367:10:::1;:23:::0;;-1:-1:-1;;;;;;44367:23:0::1;::::0;;::::1;::::0;;44340:8:::1;44401:13:::0;;44448:2:::1;44310:6;44434:16:::0;14680:102;;;;14731:5;14715:21;;-1:-1:-1;;14715:21:0;;;14756:14;;-1:-1:-1;5623:36:1;;14756:14:0;;5611:2:1;5596:18;14756:14:0;;;;;;;14680:102;14291:498;44258:208::o;47645:1044::-;47728:12;47771:6;-1:-1:-1;;;;;47761:16:0;:6;-1:-1:-1;;;;;47761:16:0;;;47753:31;;;;-1:-1:-1;;;47753:31:0;;5872:2:1;47753:31:0;;;5854:21:1;5911:1;5891:18;;;5884:29;-1:-1:-1;;;5929:18:1;;;5922:32;5971:18;;47753:31:0;5670:325:1;47753:31:0;47825:14;47841;47868:6;-1:-1:-1;;;;;47859:15:0;:6;-1:-1:-1;;;;;47859:15:0;;:53;;47897:6;47905;47859:53;;;47878:6;47886;47859:53;47824:88;;-1:-1:-1;47824:88:0;-1:-1:-1;;;;;;47931:20:0;;47923:35;;;;-1:-1:-1;;;47923:35:0;;6202:2:1;47923:35:0;;;6184:21:1;6241:1;6221:18;;;6214:29;-1:-1:-1;;;6259:18:1;;;6252:32;6301:18;;47923:35:0;6000:325:1;47923:35:0;-1:-1:-1;;;;;47999:15:0;;;48042:1;47999:15;;;:7;:15;;;;;;;;:23;;;;;;;;;;:31;;;;;;;;;;;;:45;47991:60;;;;-1:-1:-1;;;47991:60:0;;6532:2:1;47991:60:0;;;6514:21:1;6571:1;6551:18;;;6544:29;-1:-1:-1;;;6589:18:1;;;6582:32;6631:18;;47991:60:0;6330:325:1;47991:60:0;48137:40;;-1:-1:-1;;6909:2:1;6905:15;;;6901:24;;48137:40:0;;;6889:37:1;6960:15;;;6956:24;6942:12;;;6935:46;7027:14;;7020:22;7015:3;7011:32;6997:12;;;6990:54;48112:12:0;;7060::1;;48137:40:0;;;-1:-1:-1;;48137:40:0;;;;;;;;;;48127:51;;48137:40;48127:51;;;;48251:6;48242:50;;-1:-1:-1;;;;;48242:50:0;;;-1:-1:-1;;;;;;48242:50:0;;;-1:-1:-1;;;48242:50:0;;;-1:-1:-1;;;;;;48242:50:0;;;;;;;;;;;48243:6;48242:50;;;;;;;;;;;;;;;48127:51;-1:-1:-1;48243:6:0;;48127:51;;48318:21;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;48303:36;;48350:7;-1:-1:-1;;;;;48350:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;48415:15:0;;;;;;;:7;:15;;;;;;;;:23;;;;;;;;;;;;:31;;;;;;;;;;;;:38;;;;;-1:-1:-1;;;;;;48415:38:0;;;;;;;;48464:15;;;;;;;;;:23;;;;;;;;:31;;;;;;;;:38;;;;;;;;48558:8;:19;;-1:-1:-1;48558:19:0;;;;;;;;;;;;;;;;;;;48588:12;;;:6;:12;;;;;;:19;;-1:-1:-1;;48588:19:0;;;;;;;48665:15;;48623:58;;7279:41:1;;;7336:18;;;7329:60;;;;7405:18;;;7398:34;48415:38:0;;-1:-1:-1;48415:38:0;;:23;48623:58;;7267:2:1;7252:18;48623:58:0;;;;;;;47742:947;;;;47645:1044;;;;;:::o;47389:116::-;47436:7;47473:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;47463:34;;;;;;47456:41;;47389:116;:::o;48697:148::-;48755:10;;-1:-1:-1;;;;;48755:10:0;48741;:24;48733:50;;;;-1:-1:-1;;;48733:50:0;;7645:2:1;48733:50:0;;;7627:21:1;7684:2;7664:18;;;7657:30;-1:-1:-1;;;7703:18:1;;;7696:43;7756:18;;48733:50:0;7443:337:1;48733:50:0;48823:4;48809:11;:18;48697:148::o;44907:145::-;44980:6;;;;;-1:-1:-1;;;;;44980:6:0;44966:10;:20;44958:58;;;;-1:-1:-1;;;44958:58:0;;4654:2:1;44958:58:0;;;4636:21:1;4693:2;4673:18;;;4666:30;-1:-1:-1;;;4712:18:1;;;4705:55;4777:18;;44958:58:0;4452:349:1;44958:58:0;45027:8;:17;;;;;;;-1:-1:-1;;45027:17:0;;;;;;;;;44907:145::o;45406:348::-;45492:10;;-1:-1:-1;;;;;45492:10:0;45478;:24;45470:52;;;;-1:-1:-1;;;45470:52:0;;;;;;;:::i;:::-;45549:11;;45541:4;:19;;45533:44;;;;-1:-1:-1;;;45533:44:0;;3965:2:1;45533:44:0;;;3947:21:1;4004:2;3984:18;;;3977:30;-1:-1:-1;;;4023:18:1;;;4016:42;4075:18;;45533:44:0;3763:336:1;45533:44:0;45596:9;45588:41;;;;-1:-1:-1;;;45588:41:0;;4306:2:1;45588:41:0;;;4288:21:1;4345:2;4325:18;;;4318:30;-1:-1:-1;;;4364:18:1;;;4357:49;4423:18;;45588:41:0;4104:343:1;45588:41:0;45644:7;45640:107;;;45668:9;:16;-1:-1:-1;45406:348:0:o;45640:107::-;45717:11;:18;-1:-1:-1;45406:348:0:o;45234:164::-;45304:17;;-1:-1:-1;;;;;45304:17:0;45290:10;:31;45282:67;;;;-1:-1:-1;;;45282:67:0;;7987:2:1;45282:67:0;;;7969:21:1;8026:2;8006:18;;;7999:30;8065:25;8045:18;;;8038:53;8108:18;;45282:67:0;7785:347:1;45282:67:0;45373:17;;45360:10;:30;;-1:-1:-1;;;;;;45360:30:0;-1:-1:-1;;;;;45373:17:0;;;45360:30;;;;;;45234:164::o;-1:-1:-1:-;;;;;;;;:::o;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;407:173::-;475:20;;-1:-1:-1;;;;;524:31:1;;514:42;;504:70;;570:1;567;560:12;504:70;407:173;;;:::o;585:254::-;653:6;661;714:2;702:9;693:7;689:23;685:32;682:52;;;730:1;727;720:12;682:52;753:29;772:9;753:29;:::i;:::-;743:39;829:2;814:18;;;;801:32;;-1:-1:-1;;;585:254:1:o;1026:186::-;1085:6;1138:2;1126:9;1117:7;1113:23;1109:32;1106:52;;;1154:1;1151;1144:12;1106:52;1177:29;1196:9;1177:29;:::i;1217:118::-;1303:5;1296:13;1289:21;1282:5;1279:32;1269:60;;1325:1;1322;1315:12;1340:241;1396:6;1449:2;1437:9;1428:7;1424:23;1420:32;1417:52;;;1465:1;1462;1455:12;1417:52;1504:9;1491:23;1523:28;1545:5;1523:28;:::i;1586:389::-;1660:6;1668;1676;1729:2;1717:9;1708:7;1704:23;1700:32;1697:52;;;1745:1;1742;1735:12;1697:52;1768:29;1787:9;1768:29;:::i;:::-;1758:39;;1816:38;1850:2;1839:9;1835:18;1816:38;:::i;:::-;1806:48;;1904:2;1893:9;1889:18;1876:32;1917:28;1939:5;1917:28;:::i;:::-;1964:5;1954:15;;;1586:389;;;;;:::o;2354:309::-;2419:6;2427;2480:2;2468:9;2459:7;2455:23;2451:32;2448:52;;;2496:1;2493;2486:12;2448:52;2535:9;2522:23;2554:28;2576:5;2554:28;:::i;3419:339::-;3621:2;3603:21;;;3660:2;3640:18;;;3633:30;-1:-1:-1;;;3694:2:1;3679:18;;3672:45;3749:2;3734:18;;3419:339::o;4806:245::-;4873:6;4926:2;4914:9;4905:7;4901:23;4897:32;4894:52;;;4942:1;4939;4932:12;4894:52;4974:9;4968:16;4993:28;5015:5;4993:28;:::i
Swarm Source
ipfs://9b55840b8233d336e14811b59252a6e23acbbfb38f7b9f8eaf5bef94c7fea095
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.