Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Pause | 3589390 | 565 days ago | IN | 0 ETH | 0.00002155 |
Latest 10 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
5159965 | 530 days ago | Contract Creation | 0 ETH | |||
3510621 | 565 days ago | Contract Creation | 0 ETH | |||
2866380 | 575 days ago | Contract Creation | 0 ETH | |||
103868 | 678 days ago | Contract Creation | 0 ETH | |||
91920 | 680 days ago | Contract Creation | 0 ETH | |||
39950 | 686 days ago | Contract Creation | 0 ETH | |||
39726 | 686 days ago | Contract Creation | 0 ETH | |||
39656 | 686 days ago | Contract Creation | 0 ETH | |||
18988 | 689 days ago | Contract Creation | 0 ETH | |||
18524 | 689 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
LeetSwapV2Factory
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./LeetSwapV2Pair.sol"; import "./interfaces/ITradingFeesOracle.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract LeetSwapV2Factory is ILeetSwapV2Factory, Ownable { bool public isPaused; address public pauser; address public pendingPauser; ITradingFeesOracle public tradingFeesOracle; uint256 public protocolFeesShare; address public protocolFeesRecipient; mapping(address => mapping(address => mapping(bool => address))) internal _getPair; uint256 internal _tradingFees; address[] public allPairs; mapping(address => bool) public isPair; // simplified check if it's a pair, given that `stable` flag might not be available in peripherals address internal _temp0; address internal _temp1; bool internal _temp; event PairCreated( address indexed token0, address indexed token1, bool stable, address pair, uint256 ); error IdenticalAddress(); error PairExists(); error ZeroAddress(); error Unauthorized(); constructor() { pauser = msg.sender; isPaused = false; protocolFeesRecipient = msg.sender; _tradingFees = 30; protocolFeesShare = 5000; } function allPairsLength() external view returns (uint256) { return allPairs.length; } function setPauser(address _pauser) external { if (msg.sender != pauser) revert Unauthorized(); pendingPauser = _pauser; } function acceptPauser() external { if (msg.sender != pendingPauser) revert Unauthorized(); pauser = pendingPauser; } function setPause(bool _state) external { if (msg.sender != pauser) revert Unauthorized(); isPaused = _state; } function pairCodeHash() external pure returns (bytes32) { return keccak256(type(LeetSwapV2Pair).creationCode); } function getInitializable() external view returns ( address, address, bool ) { return (_temp0, _temp1, _temp); } function getPair( address tokenA, address tokenB, bool stable ) external view override returns (address) { return _getPair[tokenA][tokenB][stable]; } // UniswapV2 fallback function getPair(address tokenA, address tokenB) external view returns (address) { return _getPair[tokenA][tokenB][false]; } function createPair( address tokenA, address tokenB, bool stable ) public returns (address pair) { if (tokenA == tokenB) revert IdenticalAddress(); (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); if (token0 == address(0)) revert ZeroAddress(); if (_getPair[token0][token1][stable] != address(0)) revert PairExists(); bytes32 salt = keccak256(abi.encodePacked(token0, token1, stable)); // notice salt includes stable as well, 3 parameters (_temp0, _temp1, _temp) = (token0, token1, stable); pair = address(new LeetSwapV2Pair{salt: salt}()); _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); } // UniswapV2 fallback function createPair(address tokenA, address tokenB) external returns (address pair) { return createPair(tokenA, tokenB, false); } function tradingFees(address pair, address to) external view returns (uint256 fees) { if (address(tradingFeesOracle) == address(0)) { fees = _tradingFees; } else { fees = tradingFeesOracle.getTradingFees(pair, to); } return fees > 100 ? 100 : fees; // max 1% fees } // **** ADMIN FUNCTIONS **** function setTradingFeesOracle(ITradingFeesOracle _tradingFeesOracle) external onlyOwner { tradingFeesOracle = _tradingFeesOracle; } function setProtocolFeesRecipient(address _protocolFeesRecipient) external onlyOwner { protocolFeesRecipient = _protocolFeesRecipient; } function setTradingFees(uint256 _fee) external onlyOwner { _tradingFees = _fee; } function setProtocolFeesShare(uint256 _protocolFeesShare) external onlyOwner { protocolFeesShare = _protocolFeesShare > 5000 ? 5000 : _protocolFeesShare; // max 50% } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // Base V1 Fees contract is 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 LeetSwapV2Fees { address internal immutable pair; // The pair it is bonded to address internal immutable token0; // token0 of pair, saved localy and statically for gas optimization address internal immutable token1; // Token1 of pair, saved localy and statically for gas optimization error InvalidToken(); error TransferFailed(); error Unauthorized(); constructor(address _token0, address _token1) { pair = msg.sender; token0 = _token0; token1 = _token1; } function _safeTransfer( address token, address to, uint256 value ) internal { if (token.code.length == 0) revert InvalidToken(); bool success = IERC20(token).transfer(to, value); if (!success) revert TransferFailed(); } // Allow the pair to transfer fees to users function claimFeesFor( address recipient, uint256 amount0, uint256 amount1 ) external { if (msg.sender != pair) revert Unauthorized(); if (amount0 > 0) _safeTransfer(token0, recipient, amount0); if (amount1 > 0) _safeTransfer(token1, recipient, amount1); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./LeetSwapV2Fees.sol"; import "./interfaces/ILeetSwapV2Factory.sol"; import "./interfaces/ILeetSwapV2Pair.sol"; import "./interfaces/ILeetSwapV2Callee.sol"; import "@leetswap/libraries/Math.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; // The base pair of pools, either stable or volatile contract LeetSwapV2Pair is ILeetSwapV2Pair { uint8 public constant decimals = 18; // Used to denote stable or volatile pair, not immutable since construction happens in the initialize method for CREATE2 deterministic addresses bool public immutable stable; uint256 public totalSupply = 0; mapping(address => mapping(address => uint256)) public allowance; mapping(address => uint256) public balanceOf; bytes32 internal DOMAIN_SEPARATOR; // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 internal constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint256) public nonces; uint256 public constant MINIMUM_LIQUIDITY = 10**3; address public immutable token0; address public immutable token1; address public immutable fees; address public immutable factory; // Structure to capture time period observations every 30 minutes, used for local oracles struct Observation { uint256 timestamp; uint256 reserve0Cumulative; uint256 reserve1Cumulative; } // Capture oracle reading every 30 minutes uint256 constant periodSize = 1800; Observation[] public observations; uint256 public reserve0; uint256 public reserve1; uint256 public blockTimestampLast; uint256 public reserve0CumulativeLast; uint256 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 uint256 public index0 = 0; uint256 public index1 = 0; // position assigned to each LP to track their current index0 & index1 vs the global position mapping(address => uint256) public supplyIndex0; mapping(address => uint256) public supplyIndex1; // tracks the amount of unclaimed, but claimable tokens off of fees for token0 and token1 mapping(address => uint256) public claimable0; mapping(address => uint256) public claimable1; event Fees(address indexed sender, uint256 amount0, uint256 amount1); event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn( address indexed sender, uint256 amount0, uint256 amount1, address indexed to ); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); event Sync(uint256 reserve0, uint256 reserve1); event Claim( address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1 ); event Transfer(address indexed from, address indexed to, uint256 amount); event Approval( address indexed owner, address indexed spender, uint256 amount ); error DEXPaused(); error InvalidToken(); error TransferFailed(); error InsufficientOutputAmount(); error InsufficientInputAmount(); error InsufficientLiquidity(); error ReentrancyGuard(); error DeadlineExpired(); error InsufficientLiquidityMinted(); error InsufficientLiquidityBurned(); error InvariantNotRespected(); error InvalidSwapRecipient(); error InvalidSignature(); constructor() { factory = msg.sender; (address _token0, address _token1, bool _stable) = ILeetSwapV2Factory( msg.sender ).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); fees = address(new LeetSwapV2Fees(_token0, _token1)); observations.push(Observation(block.timestamp, 0, 0)); } function decimals0() internal view returns (uint256) { return 10**IERC20Metadata(token0).decimals(); } function decimals1() internal view returns (uint256) { return 10**IERC20Metadata(token1).decimals(); } function name() public view returns (string memory) { if (stable) { return string( abi.encodePacked( "LeetSwapV2 StableV1 Pair - ", IERC20Metadata(token0).symbol(), "/", IERC20Metadata(token1).symbol() ) ); } return string( abi.encodePacked( "LeetSwapV2 VolatileV1 Pair - ", IERC20Metadata(token0).symbol(), "/", IERC20Metadata(token1).symbol() ) ); } function symbol() public view returns (string memory) { if (stable) { return string( abi.encodePacked( "sLS2-", IERC20Metadata(token0).symbol(), "/", IERC20Metadata(token1).symbol() ) ); } return string( abi.encodePacked( "vLS2-", IERC20Metadata(token0).symbol(), "/", IERC20Metadata(token1).symbol() ) ); } // simple re-entrancy check uint256 internal _unlocked = 1; modifier lock() { if (_unlocked != 1) revert ReentrancyGuard(); _unlocked = 2; _; _unlocked = 1; } function observationLength() external view returns (uint256) { return observations.length; } function lastObservation() public view returns (Observation memory) { return observations[observations.length - 1]; } function metadata() external view returns ( uint256 dec0, uint256 dec1, uint256 r0, uint256 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); } // claim accumulated but unclaimed fees (viewable via claimable0 and claimable1) function claimFees() external returns (uint256 claimed0, uint256 claimed1) { return claimFeesFor(msg.sender); } function claimFeesFor(address recipient) public lock returns (uint256 claimed0, uint256 claimed1) { _updateFor(recipient); claimed0 = claimable0[recipient]; claimed1 = claimable1[recipient]; claimable0[recipient] = 0; claimable1[recipient] = 0; LeetSwapV2Fees(fees).claimFeesFor(recipient, claimed0, claimed1); emit Claim(msg.sender, recipient, claimed0, claimed1); } function claimableFeesFor(address account) public view returns (uint256 _claimable0, uint256 _claimable1) { uint256 _supplied = balanceOf[account]; _claimable0 = claimable0[account]; _claimable1 = claimable1[account]; if (_supplied > 0) { uint256 _delta0 = index0 - supplyIndex0[account]; uint256 _delta1 = index1 - supplyIndex1[account]; if (_delta0 > 0) { uint256 _share = (_supplied * _delta0) / 1e18; _claimable0 += _share; } if (_delta1 > 0) { uint256 _share = (_supplied * _delta1) / 1e18; _claimable1 += _share; } } } function claimableFees() external view returns (uint256 _claimable0, uint256 _claimable1) { return claimableFeesFor(msg.sender); } // Used to transfer fees when calling _update[01] function _transferFeesSupportingTaxTokens(address token, uint256 amount) public returns (uint256) { if (amount == 0) { return 0; } uint256 balanceBefore = IERC20(token).balanceOf(fees); _safeTransfer(token, fees, amount); uint256 balanceAfter = IERC20(token).balanceOf(fees); return balanceAfter - balanceBefore; } // Accrue fees on token0 function _update0(uint256 amount) internal { uint256 _protocolFeesShare = ILeetSwapV2Factory(factory) .protocolFeesShare(); address _protocolFeesRecipient = ILeetSwapV2Factory(factory) .protocolFeesRecipient(); uint256 _protocolFeesAmount = (amount * _protocolFeesShare) / 10000; amount = _transferFeesSupportingTaxTokens( token0, amount - _protocolFeesAmount ); if (_protocolFeesAmount > 0) _safeTransfer(token0, _protocolFeesRecipient, _protocolFeesAmount); uint256 _ratio = (amount * 1e18) / totalSupply; if (_ratio > 0) { index0 += _ratio; } emit Fees(msg.sender, amount, 0); } // Accrue fees on token1 function _update1(uint256 amount) internal { uint256 _protocolFeesShare = ILeetSwapV2Factory(factory) .protocolFeesShare(); address _protocolFeesRecipient = ILeetSwapV2Factory(factory) .protocolFeesRecipient(); uint256 _protocolFeesAmount = (amount * _protocolFeesShare) / 10000; amount = _transferFeesSupportingTaxTokens( token1, amount - _protocolFeesAmount ); if (_protocolFeesAmount > 0) _safeTransfer(token1, _protocolFeesRecipient, _protocolFeesAmount); uint256 _ratio = (amount * 1e18) / totalSupply; if (_ratio > 0) { index1 += _ratio; } emit Fees(msg.sender, 0, amount); } // 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 { uint256 _supplied = balanceOf[recipient]; // get LP balance of `recipient` if (_supplied > 0) { uint256 _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient uint256 _supplyIndex1 = supplyIndex1[recipient]; uint256 _index0 = index0; // get global index0 for accumulated fees uint256 _index1 = index1; supplyIndex0[recipient] = _index0; // update user current position to global position supplyIndex1[recipient] = _index1; uint256 _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued uint256 _delta1 = _index1 - _supplyIndex1; if (_delta0 > 0) { uint256 _share = (_supplied * _delta0) / 1e18; // add accrued difference for each supplied token claimable0[recipient] += _share; } if (_delta1 > 0) { uint256 _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 ( uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast ) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = blockTimestampLast; } // update reserves and, on the first call per block, price accumulators function _update( uint256 balance0, uint256 balance1, uint256 _reserve0, uint256 _reserve1 ) internal { uint256 blockTimestamp = block.timestamp; uint256 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); } // produces the cumulative price using counterfactuals to save gas and avoid a call to sync. function currentCumulativePrices() public view returns ( uint256 reserve0Cumulative, uint256 reserve1Cumulative, uint256 blockTimestamp ) { blockTimestamp = block.timestamp; reserve0Cumulative = reserve0CumulativeLast; reserve1Cumulative = reserve1CumulativeLast; // if time has elapsed since the last update on the pair, mock the accumulated price values ( uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast ) = getReserves(); if (_blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint256 timeElapsed = blockTimestamp - _blockTimestampLast; reserve0Cumulative += _reserve0 * timeElapsed; reserve1Cumulative += _reserve1 * timeElapsed; } } // gives the current twap price measured from amountIn * tokenIn gives amountOut function current(address tokenIn, uint256 amountIn) external view returns (uint256 amountOut) { Observation memory _observation = lastObservation(); ( uint256 reserve0Cumulative, uint256 reserve1Cumulative, ) = currentCumulativePrices(); if (block.timestamp == _observation.timestamp) { _observation = observations[observations.length - 2]; } uint256 timeElapsed = block.timestamp - _observation.timestamp; uint256 _reserve0 = (reserve0Cumulative - _observation.reserve0Cumulative) / timeElapsed; uint256 _reserve1 = (reserve1Cumulative - _observation.reserve1Cumulative) / timeElapsed; amountOut = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); } // as per `current`, however allows user configured granularity, up to the full window size function quote( address tokenIn, uint256 amountIn, uint256 granularity ) external view returns (uint256 amountOut) { uint256[] memory _prices = sample(tokenIn, amountIn, granularity, 1); uint256 priceAverageCumulative; for (uint256 i = 0; i < _prices.length; i++) { priceAverageCumulative += _prices[i]; } return priceAverageCumulative / granularity; } // returns a memory set of twap prices function prices( address tokenIn, uint256 amountIn, uint256 points ) external view returns (uint256[] memory) { return sample(tokenIn, amountIn, points, 1); } function sample( address tokenIn, uint256 amountIn, uint256 points, uint256 window ) public view returns (uint256[] memory) { uint256[] memory _prices = new uint256[](points); uint256 length = observations.length - 1; uint256 i = length - (points * window); uint256 nextIndex = 0; uint256 index = 0; for (; i < length; i += window) { nextIndex = i + window; uint256 timeElapsed = observations[nextIndex].timestamp - observations[i].timestamp; uint256 _reserve0 = (observations[nextIndex].reserve0Cumulative - observations[i].reserve0Cumulative) / timeElapsed; uint256 _reserve1 = (observations[nextIndex].reserve1Cumulative - observations[i].reserve1Cumulative) / timeElapsed; _prices[index] = _getAmountOut( amountIn, tokenIn, _reserve0, _reserve1 ); index = index + 1; } return _prices; } // this low-level function should be called from a contract which performs important safety checks // standard uniswap v2 implementation function mint(address to) external lock returns (uint256 liquidity) { (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); uint256 _balance0 = IERC20Metadata(token0).balanceOf(address(this)); uint256 _balance1 = IERC20Metadata(token1).balanceOf(address(this)); uint256 _amount0 = _balance0 - _reserve0; uint256 _amount1 = _balance1 - _reserve1; uint256 _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 ); } if (liquidity <= 0) revert InsufficientLiquidityMinted(); _mint(to, liquidity); _update(_balance0, _balance1, _reserve0, _reserve1); emit Mint(msg.sender, _amount0, _amount1); } // 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 (uint256 amount0, uint256 amount1) { (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); (address _token0, address _token1) = (token0, token1); uint256 _balance0 = IERC20Metadata(_token0).balanceOf(address(this)); uint256 _balance1 = IERC20Metadata(_token1).balanceOf(address(this)); uint256 _liquidity = balanceOf[address(this)]; uint256 _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 if (amount0 <= 0 || amount1 <= 0) revert InsufficientLiquidityBurned(); _burn(address(this), _liquidity); _safeTransfer(_token0, to, amount0); _safeTransfer(_token1, to, amount1); _balance0 = IERC20Metadata(_token0).balanceOf(address(this)); _balance1 = IERC20Metadata(_token1).balanceOf(address(this)); _update(_balance0, _balance1, _reserve0, _reserve1); emit Burn(msg.sender, amount0, amount1, to); } // this low-level function should be called from a contract which performs important safety checks function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external lock { if (ILeetSwapV2Factory(factory).isPaused()) revert DEXPaused(); if (amount0Out <= 0 && amount1Out <= 0) revert InsufficientOutputAmount(); (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); if (amount0Out >= _reserve0 || amount1Out >= _reserve1) revert InsufficientLiquidity(); uint256 _balance0; uint256 _balance1; { // scope for _token{0,1}, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); if (to == _token0 || to == _token1) revert InvalidSwapRecipient(); if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens if (data.length > 0) ILeetSwapV2Callee(to).hook( msg.sender, amount0Out, amount1Out, data ); // callback, used for flash loans _balance0 = IERC20Metadata(_token0).balanceOf(address(this)); _balance1 = IERC20Metadata(_token1).balanceOf(address(this)); } uint256 amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0; uint256 amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0; if (amount0In <= 0 && amount1In <= 0) revert InsufficientInputAmount(); { // scope for reserve{0,1}Adjusted, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); uint256 _tradingFees = ILeetSwapV2Factory(factory).tradingFees( address(this), to ); if (amount0In > 0) _update0((amount0In * _tradingFees) / 10000); // accrue fees for token0 and move them out of pool if (amount1In > 0) _update1((amount1In * _tradingFees) / 10000); // accrue fees for token1 and move them out of pool _balance0 = IERC20Metadata(_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 = IERC20Metadata(_token1).balanceOf(address(this)); // The curve, either x3y+y3x for stable pools, or x*y for volatile pools if (_k(_balance0, _balance1) < _k(_reserve0, _reserve1)) revert InvariantNotRespected(); } _update(_balance0, _balance1, _reserve0, _reserve1); emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); } // force balances to match reserves function skim(address to) external lock { (address _token0, address _token1) = (token0, token1); _safeTransfer( _token0, to, IERC20Metadata(_token0).balanceOf(address(this)) - (reserve0) ); _safeTransfer( _token1, to, IERC20Metadata(_token1).balanceOf(address(this)) - (reserve1) ); } // force reserves to match balances function sync() external lock { _update( IERC20Metadata(token0).balanceOf(address(this)), IERC20Metadata(token1).balanceOf(address(this)), reserve0, reserve1 ); } function _f(uint256 x0, uint256 y) internal pure returns (uint256) { return (x0 * ((((y * y) / 1e18) * y) / 1e18)) / 1e18 + (((((x0 * x0) / 1e18) * x0) / 1e18) * y) / 1e18; } function _d(uint256 x0, uint256 y) internal pure returns (uint256) { return (3 * x0 * ((y * y) / 1e18)) / 1e18 + ((((x0 * x0) / 1e18) * x0) / 1e18); } function _get_y( uint256 x0, uint256 xy, uint256 y ) internal pure returns (uint256) { for (uint256 i = 0; i < 255; i++) { uint256 y_prev = y; uint256 k = _f(x0, y); if (k < xy) { uint256 dy = ((xy - k) * 1e18) / _d(x0, y); y = y + dy; } else { uint256 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( uint256 amountIn, address tokenIn, address to ) public view returns (uint256) { (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); uint256 _tradingFees = ILeetSwapV2Factory(factory).tradingFees( address(this), to ); amountIn -= (amountIn * _tradingFees) / 10000; // remove fee from amount received return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); } function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256) { return getAmountOut(amountIn, tokenIn, msg.sender); } function _getAmountOut( uint256 amountIn, address tokenIn, uint256 _reserve0, uint256 _reserve1 ) internal view returns (uint256) { if (stable) { uint256 xy = _k(_reserve0, _reserve1); _reserve0 = (_reserve0 * 1e18) / decimals0(); _reserve1 = (_reserve1 * 1e18) / decimals1(); (uint256 reserveA, uint256 reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0); amountIn = tokenIn == token0 ? (amountIn * 1e18) / decimals0() : (amountIn * 1e18) / decimals1(); uint256 y = reserveB - _get_y(amountIn + reserveA, xy, reserveB); return (y * (tokenIn == token0 ? decimals1() : decimals0())) / 1e18; } else { (uint256 reserveA, uint256 reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0); return (amountIn * reserveB) / (reserveA + amountIn); } } function _k(uint256 x, uint256 y) internal view returns (uint256) { if (stable) { uint256 _x = (x * 1e18) / decimals0(); uint256 _y = (y * 1e18) / decimals1(); uint256 _a = (_x * _y) / 1e18; uint256 _b = ((_x * _x) / 1e18 + (_y * _y) / 1e18); return (_a * _b) / 1e18; // x3y+y3x >= k } else { return x * y; // xy >= k } } function _mint(address dst, uint256 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, uint256 amount) internal { _updateFor(dst); totalSupply -= amount; balanceOf[dst] -= amount; emit Transfer(dst, address(0), amount); } function approve(address spender, uint256 amount) external returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external { if (deadline < block.timestamp) revert DeadlineExpired(); 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); if (recoveredAddress == address(0) || recoveredAddress != owner) revert InvalidSignature(); allowance[owner][spender] = value; emit Approval(owner, spender, value); } function transfer(address dst, uint256 amount) external returns (bool) { _transferTokens(msg.sender, dst, amount); return true; } function transferFrom( address src, address dst, uint256 amount ) external returns (bool) { address spender = msg.sender; uint256 spenderAllowance = allowance[src][spender]; if (spender != src && spenderAllowance != type(uint256).max) { uint256 newAllowance = spenderAllowance - amount; allowance[src][spender] = newAllowance; emit Approval(src, spender, newAllowance); } _transferTokens(src, dst, amount); return true; } function _transferTokens( address src, address dst, uint256 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 { if (token.code.length == 0) revert InvalidToken(); bool success = IERC20(token).transfer(to, value); if (!success) revert TransferFailed(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ILeetSwapV2Callee { function hook( address sender, uint256 amount0, uint256 amount1, bytes calldata data ) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; interface ILeetSwapV2Factory { function allPairsLength() external view returns (uint256); function isPair(address pair) external view returns (bool); function pairCodeHash() external pure returns (bytes32); function getPair( address tokenA, address token, bool stable ) external view returns (address); function createPair( address tokenA, address tokenB, bool stable ) external returns (address); function createPair(address tokenA, address tokenB) external returns (address); function getInitializable() external view returns ( address token0, address token1, bool stable ); function protocolFeesShare() external view returns (uint256); function protocolFeesRecipient() external view returns (address); function tradingFees(address pair, address to) external view returns (uint256); function isPaused() external view returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; interface ILeetSwapV2Pair { function factory() external view returns (address); function fees() external view returns (address); function transferFrom( address src, address dst, uint256 amount ) external returns (bool); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function burn(address to) external returns (uint256 amount0, uint256 amount1); function mint(address to) external returns (uint256 liquidity); function getReserves() external view returns ( uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast ); function getAmountOut(uint256, address) external view returns (uint256); function current(address tokenIn, uint256 amountIn) external view returns (uint256); function token0() external view returns (address); function token1() external view returns (address); function stable() external view returns (bool); function balanceOf(address) external view returns (uint256); //LP token pricing function sample( address tokenIn, uint256 amountIn, uint256 points, uint256 window ) external view returns (uint256[] memory); function quote( address tokenIn, uint256 amountIn, uint256 granularity ) external view returns (uint256); function claimFeesFor(address account) external returns (uint256 claimed0, uint256 claimed1); function claimFees() external returns (uint256 claimed0, uint256 claimed1); function claimableFeesFor(address account) external returns (uint256 claimed0, uint256 claimed1); function claimableFees() external returns (uint256 claimed0, uint256 claimed1); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; interface ITradingFeesOracle { function getTradingFees(address pair, address to) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Math { function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
{ "remappings": [ "@leetswap/=src/", "@openzeppelin/=lib/openzeppelin-contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"IdenticalAddress","type":"error"},{"inputs":[],"name":"PairExists","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":"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":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","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":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"pendingPauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeesRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeesShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":[{"internalType":"address","name":"_protocolFeesRecipient","type":"address"}],"name":"setProtocolFeesRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolFeesShare","type":"uint256"}],"name":"setProtocolFeesShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setTradingFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITradingFeesOracle","name":"_tradingFeesOracle","type":"address"}],"name":"setTradingFeesOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"tradingFees","outputs":[{"internalType":"uint256","name":"fees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingFeesOracle","outputs":[{"internalType":"contract ITradingFeesOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001a33610059565b60018054336001600160a01b031991821681179092556000805460ff60a01b19169055600580549091169091179055601e6007556113886004556100a9565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61550b806100b86000396000f3fe60806040523480156200001157600080fd5b5060043610620001af5760003560e01c80638da5cb5b11620000f0578063bedb86fb11620000a3578063e5e31b13116200007a578063e5e31b1314620003c3578063e6a4390514620003e9578063eb13c4cf146200042c578063f2fde38b146200046557600080fd5b8063bedb86fb146200037e578063c9c653961462000395578063e12ab55914620003ac57600080fd5b80638da5cb5b146200030a5780639a7165e4146200031c5780639aab924814620003305780639fd0506d146200033a578063afda13e9146200034e578063b187bd26146200035857600080fd5b8063574f2ba3116200016657806368930637116200013d5780636893063714620002be578063715018a614620002d25780637a72f06f14620002dc57806382dfdce414620002f357600080fd5b8063574f2ba3146200024d5780635cf7310814620002605780636801cc30146200027757600080fd5b8063064c1a7714620001b4578063167a6f9014620001e55780631e3dd18b14620001f1578063288eb1a314620002085780632d88af4a146200021f57806340d1b27a1462000236575b600080fd5b600354620001c8906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001ef6200047c565b005b620001c86200020236600462000b11565b620004cb565b620001ef6200021936600462000b11565b620004f6565b620001ef6200023036600462000b41565b6200051b565b620001ef6200024736600462000b41565b62000568565b6008545b604051908152602001620001dc565b620002516200027136600462000b61565b62000594565b620001c86200028836600462000bb5565b6001600160a01b039283166000908152600660209081526040808320948616835293815283822092151582529190915220541690565b600554620001c8906001600160a01b031681565b620001ef62000648565b620001ef620002ed36600462000b41565b62000660565b620001c86200030436600462000bb5565b6200068c565b6000546001600160a01b0316620001c8565b600254620001c8906001600160a01b031681565b6200025162000938565b600154620001c8906001600160a01b031681565b6200025160045481565b6000546200036d90600160a01b900460ff1681565b6040519015158152602001620001dc565b620001ef6200038f36600462000c03565b6200096c565b620001c8620003a636600462000b61565b620009b5565b620001ef620003bd36600462000b11565b620009c5565b6200036d620003d436600462000b41565b60096020526000908152604090205460ff1681565b620001c8620003fa36600462000b61565b6001600160a01b0391821660009081526006602090815260408083209385168352928152828220828052905220541690565b600a54600b54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff16151590820152606001620001dc565b620001ef6200047636600462000b41565b620009d4565b6002546001600160a01b03163314620004a7576040516282b42960e81b815260040160405180910390fd5b600254600180546001600160a01b0319166001600160a01b03909216919091179055565b60088181548110620004dc57600080fd5b6000918252602090912001546001600160a01b0316905081565b6200050062000a57565b611388811162000511578062000515565b6113885b60045550565b6001546001600160a01b0316331462000546576040516282b42960e81b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6200057262000a57565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6003546000906001600160a01b0316620005b257506007546200062e565b60035460405163ab898da760e01b81526001600160a01b03858116600483015284811660248301529091169063ab898da790604401602060405180830381865afa15801562000605573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200062b919062000c21565b90505b606481116200063e578062000641565b60645b9392505050565b6200065262000a57565b6200065e600062000ab3565b565b6200066a62000a57565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000826001600160a01b0316846001600160a01b031603620006c15760405163065af08d60e01b815260040160405180910390fd5b600080846001600160a01b0316866001600160a01b031610620006e6578486620006e9565b85855b90925090506001600160a01b038216620007165760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03828116600090815260066020908152604080832085851684528252808320881515845290915290205416156200076757604051633d77e89160e01b815260040160405180910390fd5b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600b80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600a805492881692909116919091179055915081906200080e9062000b03565b8190604051809103906000f59050801580156200082f573d6000803e3d6000fd5b506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560088054600181810183557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39091018054909a1687179099558587526009855295839020805460ff1916909817909755935481519687529186019290925290840152929650907fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a35050509392505050565b6000604051806020016200094c9062000b03565b6020820181038252601f19601f8201166040525080519060200120905090565b6001546001600160a01b0316331462000997576040516282b42960e81b815260040160405180910390fd5b60008054911515600160a01b0260ff60a01b19909216919091179055565b600062000641838360006200068c565b620009cf62000a57565b600755565b620009de62000a57565b6001600160a01b03811662000a495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b62000a548162000ab3565b50565b6000546001600160a01b031633146200065e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000a40565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61489a8062000c3c83390190565b60006020828403121562000b2457600080fd5b5035919050565b6001600160a01b038116811462000a5457600080fd5b60006020828403121562000b5457600080fd5b8135620006418162000b2b565b6000806040838503121562000b7557600080fd5b823562000b828162000b2b565b9150602083013562000b948162000b2b565b809150509250929050565b8035801515811462000bb057600080fd5b919050565b60008060006060848603121562000bcb57600080fd5b833562000bd88162000b2b565b9250602084013562000bea8162000b2b565b915062000bfa6040850162000b9f565b90509250925092565b60006020828403121562000c1657600080fd5b620006418262000b9f565b60006020828403121562000c3457600080fd5b505191905056fe610120604052600080556000600b556000600c5560016011553480156200002557600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000085573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ab9190620001f3565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000de90620001c8565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000112573d6000803e3d6000fd5b506001600160a01b031660e05250506040805160608101825242815260006020820181815292820181815260058054600181018255925291517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db060039092029182015591517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db1830155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2909101555062000245565b610321806200457983390190565b80516001600160a01b0381168114620001ee57600080fd5b919050565b6000806000606084860312156200020957600080fd5b6200021484620001d6565b92506200022460208501620001d6565b9150604084015180151581146200023a57600080fd5b809150509250925092565b60805160a05160c05160e05161010051614191620003e8600039600081816107370152818161083201528181610c1701528181611665015281816129ba01528181612a4001528181612bc50152612c4b0152600081816105fa015281816119f70152818161264c015281816126cb015261270701526000818161064f015281816107670152818161095301528181610bf201528181610efe0152818161102f01528181611517015281816117ea01528181611b0f01528181611eee0152818161200b0152818161227f0152818161286901528181612ced01528181612d2301526134260152600081816103760152818161062a0152818161093201528181610bd001528181610e7801528181610fa9015281816114f40152818161175401528181611aed01528181611e6801528181611f850152818161225d015281816127e101528181612ae201528181612b18015281816130f70152818161313e015281816131f101528181613261015261339201526000818161041401528181610e52015281816114d101528181611e4201528181612dc6015261307401526141916000f3fe608060405234801561001057600080fd5b50600436106102f15760003560e01c806389afcb441161019d578063bf944dbc116100e9578063d294f093116100a2578063ebeb31db1161007c578063ebeb31db146107cf578063ec7e683d146107d7578063f140a35a146107ea578063fff6cae9146107fd57600080fd5b8063d294f09314610789578063d505accf14610791578063dd62ed3e146107a457600080fd5b8063bf944dbc14610718578063c245febc14610721578063c3192f141461072a578063c45a015514610732578063c5700a0214610759578063d21220a71461076257600080fd5b80639f767c8811610156578063a9059cbb11610130578063a9059cbb146106e0578063ba9a7a56146106f3578063bc25cf77146106fc578063bda39cad1461070f57600080fd5b80639f767c881461068d578063a1ac4d13146106ad578063a88684b0146106cd57600080fd5b806389afcb44146105b05780638a7b8cf2146105c357806395d89b41146105ed5780639af1d35a146105f55780639d63848a1461061c5780639e8cc04b1461067a57600080fd5b8063313ce5671161025c5780635881c475116102155780636a627842116101ef5780636a6278421461053557806370a082311461054857806374522292146105685780637ecebe001461059057600080fd5b80635881c475146105065780635a76f25e146105195780635e1e63251461052257600080fd5b8063313ce5671461045c57806332c0defd14610476578063392f37e91461047f578063443cb4bc146104ca5780634d5a9f8a146104d3578063517b3f82146104f357600080fd5b806318160ddd116102ae57806318160ddd146103d05780631df8c717146103e7578063205aabf1146103ef57806322be3de11461040f57806323b872dd14610436578063252c09d71461044957600080fd5b8063022c0d9f146102f657806306fdde031461030b5780630902f1ac14610329578063095ea7b31461034e5780630dfe16811461037157806313345fe1146103b0575b600080fd5b6103096103043660046139b0565b610805565b005b610313610e4e565b6040516103209190613a6a565b60405180910390f35b6006546007546008545b60408051938452602084019290925290820152606001610320565b61036161035c366004613a9d565b6110c4565b6040519015158152602001610320565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610320565b6103c36103be366004613ac9565b611131565b6040516103209190613b04565b6103d960005481565b604051908152602001610320565b610333611339565b6103d96103fd366004613b48565b600e6020526000908152604090205481565b6103617f000000000000000000000000000000000000000000000000000000000000000081565b610361610444366004613b65565b6113a8565b610333610457366004613ba6565b611471565b610464601281565b60405160ff9091168152602001610320565b6103d9600b5481565b6104876114a4565b604080519788526020880196909652948601939093526060850191909152151560808401526001600160a01b0390811660a08401521660c082015260e001610320565b6103d960065481565b6103d96104e1366004613b48565b600f6020526000908152604090205481565b6103d9610501366004613a9d565b61153c565b6103c3610514366004613bbf565b611624565b6103d960075481565b6103d9610530366004613bf4565b611633565b6103d9610543366004613b48565b61170c565b6103d9610556366004613b48565b60026020526000908152604090205481565b61057b610576366004613b48565b61196b565b60408051928352602083019190915201610320565b6103d961059e366004613b48565b60046020526000908152604090205481565b61057b6105be366004613b48565b611aa7565b6105cb611dbe565b6040805182518152602080840151908201529181015190820152606001610320565b610313611e3e565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f000000000000000000000000000000000000000000000000000000000000000016602082015201610320565b6103d9610688366004613bbf565b6120a0565b6103d961069b366004613b48565b600d6020526000908152604090205481565b6103d96106bb366004613b48565b60106020526000908152604090205481565b61057b6106db366004613b48565b61210d565b6103616106ee366004613a9d565b612207565b6103d96103e881565b61030961070a366004613b48565b61221d565b6103d9600c5481565b6103d960095481565b6103d9600a5481565b61057b61234f565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b6103d960085481565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b61057b612363565b61030961079f366004613c45565b61236f565b6103d96107b2366004613cb6565b600160209081526000928352604080842090915290825290205481565b6005546103d9565b6103d96107e5366004613a9d565b612623565b6103d96107f8366004613cef565b612793565b6103096127a0565b601154600114610828576040516345f5ce8b60e11b815260040160405180910390fd5b60026011819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa15801561088e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b29190613d14565b156108d057604051639153568960e01b815260040160405180910390fd5b841580156108dc575083155b156108fa576040516342301c2360e01b815260040160405180910390fd5b600654600754818710158061090f5750808610155b1561092d5760405163bb55fd2760e01b815260040160405180910390fd5b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148061099d5750806001600160a01b0316896001600160a01b0316145b156109bb5760405163d4f6398f60e01b815260040160405180910390fd5b8a156109cc576109cc828a8d6128ee565b89156109dd576109dd818a8c6128ee565b8615610a4a57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff7990610a179033908f908f908e908e90600401613d36565b600060405180830381600087803b158015610a3157600080fd5b505af1158015610a45573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab29190613d82565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d9190613d82565b9250505060008985610b2f9190613db1565b8311610b3c576000610b50565b610b468a86613db1565b610b509084613db1565b90506000610b5e8a86613db1565b8311610b6b576000610b7f565b610b758a86613db1565b610b7f9084613db1565b905081158015610b8d575080155b15610bab5760405163098fb56160e01b815260040160405180910390fd5b604051630b9ee62160e31b81523060048201526001600160a01b038a811660248301527f0000000000000000000000000000000000000000000000000000000000000000917f0000000000000000000000000000000000000000000000000000000000000000916000917f000000000000000000000000000000000000000000000000000000000000000090911690635cf7310890604401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c849190613d82565b90508415610cab57610cab612710610c9c8388613dc4565b610ca69190613ddb565b6129b6565b8315610cd057610cd0612710610cc18387613dc4565b610ccb9190613ddb565b612bc1565b6040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa158015610d14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d389190613d82565b6040516370a0823160e01b81523060048201529097506001600160a01b038316906370a0823190602401602060405180830381865afa158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190613d82565b9550610daf8989612dc2565b610db98888612dc2565b1015610dd857604051636458e09f60e11b815260040160405180910390fd5b505050610de784848888612edc565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601155505050505050505050565b60607f000000000000000000000000000000000000000000000000000000000000000015610fa7577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ed4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610efc9190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610f5a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f829190810190613e13565b604051602001610f93929190613eb5565b604051602081830303815290604052905090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611005573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261102d9190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561108b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b39190810190613e13565b604051602001610f93929190613f1a565b3360008181526001602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061111f9086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff81111561114e5761114e613dfd565b604051908082528060200260200182016040528015611177578160200160208202803683370190505b5060055490915060009061118d90600190613db1565b9050600061119b8587613dc4565b6111a59083613db1565b90506000805b83831015611329576111bd8784613f7f565b91506000600584815481106111d4576111d4613f92565b906000526020600020906003020160000154600584815481106111f9576111f9613f92565b9060005260206000209060030201600001546112159190613db1565b90506000816005868154811061122d5761122d613f92565b9060005260206000209060030201600101546005868154811061125257611252613f92565b90600052602060002090600302016001015461126e9190613db1565b6112789190613ddb565b90506000826005878154811061129057611290613f92565b906000526020600020906003020160020154600587815481106112b5576112b5613f92565b9060005260206000209060030201600201546112d19190613db1565b6112db9190613ddb565b90506112e98c8e8484613070565b8885815181106112fb576112fb613f92565b6020908102919091010152611311846001613f7f565b935050505086836113229190613f7f565b92506111ab565b509293505050505b949350505050565b600954600a5442600080806113576006546007546008549192909190565b9250925092508381146113a05760006113708286613db1565b905061137c8185613dc4565b6113869088613f7f565b96506113928184613dc4565b61139c9087613f7f565b9550505b505050909192565b6001600160a01b0383166000818152600160209081526040808320338085529252822054919290919082148015906113e257506000198114155b156114585760006113f38583613db1565b6001600160a01b038881166000818152600160209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6114638686866132ce565b6001925050505b9392505050565b6005818154811061148157600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b60008060008060008060006114b761338e565b6114bf613422565b600654600754929a91995097509095507f000000000000000000000000000000000000000000000000000000000000000094507f000000000000000000000000000000000000000000000000000000000000000093507f000000000000000000000000000000000000000000000000000000000000000092509050565b600080611547611dbe565b9050600080611554611339565b508451919350915042036115bc576005805461157290600290613db1565b8154811061158257611582613f92565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906115cb9042613db1565b90506000818560200151856115e09190613db1565b6115ea9190613ddb565b90506000828660400151856115ff9190613db1565b6116099190613ddb565b9050611617888a8484613070565b9998505050505050505050565b60606113318484846001611131565b600654600754604051630b9ee62160e31b81523060048201526001600160a01b038481166024830152600093929184917f00000000000000000000000000000000000000000000000000000000000000001690635cf7310890604401602060405180830381865afa1580156116ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d09190613d82565b90506127106116df8289613dc4565b6116e99190613ddb565b6116f39088613db1565b965061170187878585613070565b979650505050505050565b6000601154600114611731576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556006546007546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156117a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c79190613d82565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611831573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118559190613d82565b905060006118638584613db1565b905060006118718584613db1565b600080549192508190036118b2576103e861189461188f8486613dc4565b613482565b61189e9190613db1565b97506118ad60006103e86134f2565b6118e7565b6118e4876118c08386613dc4565b6118ca9190613ddb565b876118d58486613dc4565b6118df9190613ddb565b613584565b97505b6000881161190857604051633489be7560e21b815260040160405180910390fd5b61191289896134f2565b61191e85858989612edc565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601155509395945050505050565b600080601154600114611991576040516345f5ce8b60e11b815260040160405180910390fd5b600260115561199f8361359a565b50506001600160a01b038181166000818152600f6020908152604080832080546010909352818420805491859055939093555163299e7ae760e11b8152600481019390935260248301819052604483018290529290917f00000000000000000000000000000000000000000000000000000000000000009091169063533cf5ce90606401600060405180830381600087803b158015611a3d57600080fd5b505af1158015611a51573d6000803e3d6000fd5b505060408051858152602081018590526001600160a01b03871693503392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a360016011559092909150565b600080601154600114611acd576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556006546007546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b879190613d82565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611bd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf59190613d82565b3060009081526002602052604081205490549192509080611c168584613dc4565b611c209190613ddb565b995080611c2d8484613dc4565b611c379190613ddb565b9850891580611c44575088155b15611c625760405163749383ad60e01b815260040160405180910390fd5b611c6c30836136fa565b611c77868c8c6128ee565b611c82858c8b6128ee565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cea9190613d82565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d559190613d82565b9250611d6384848a8a612edc565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601181905550915091565b611de260405180606001604052806000815260200160008152602001600081525090565b60058054611df290600190613db1565b81548110611e0257611e02613f92565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60607f000000000000000000000000000000000000000000000000000000000000000015611f83577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611ec4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611eec9190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611f4a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f729190810190613e13565b604051602001610f93929190613fa8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611fe1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120099190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612067573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261208f9190810190613e13565b604051602001610f93929190613ff5565b6000806120b08585856001611131565b90506000805b82518110156120f8578281815181106120d1576120d1613f92565b6020026020010151826120e49190613f7f565b9150806120f081614015565b9150506120b6565b506121038482613ddb565b9695505050505050565b6001600160a01b038116600090815260026020908152604080832054600f835281842054601090935292205490918015612201576001600160a01b0384166000908152600d6020526040812054600b546121679190613db1565b6001600160a01b0386166000908152600e6020526040812054600c5492935090916121929190613db1565b905081156121c9576000670de0b6b3a76400006121af8486613dc4565b6121b99190613ddb565b90506121c58187613f7f565b9550505b80156121fe576000670de0b6b3a76400006121e48386613dc4565b6121ee9190613ddb565b90506121fa8186613f7f565b9450505b50505b50915091565b60006122143384846132ce565b50600192915050565b601154600114612240576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556006546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f00000000000000000000000000000000000000000000000000000000000000009161230d9184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa1580156122da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122fe9190613d82565b6123089190613db1565b6128ee565b6007546040516370a0823160e01b81523060048201526123459183918691906001600160a01b038416906370a08231906024016122bd565b5050600160115550565b60008061235b3361210d565b915091509091565b60008061235b3361196b565b4284101561239057604051631ab7da6b60e01b815260040160405180910390fd5b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6123b9610e4e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060038190556001600160a01b038a166000908152600490935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761248583614015565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e001604051602081830303815290604052805190602001206040516020016124fe92919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015612569573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158061259e5750886001600160a01b0316816001600160a01b031614155b156125bc57604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b038981166000818152600160209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b6000816000036126355750600061112b565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600091908516906370a0823190602401602060405180830381865afa15801561269f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c39190613d82565b90506126f0847f0000000000000000000000000000000000000000000000000000000000000000856128ee565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600091908616906370a0823190602401602060405180830381865afa15801561275a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277e9190613d82565b905061278a8282613db1565b95945050505050565b600061146a838333611633565b6011546001146127c3576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556040516370a0823160e01b81523060048201526128e7907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612830573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128549190613d82565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156128b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128dc9190613d82565b600654600754612edc565b6001601155565b826001600160a01b03163b6000036129195760405163c1ab6dc160e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390526000919085169063a9059cbb906044016020604051808303816000875af115801561296c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129909190613d14565b9050806129b0576040516312171d8360e31b815260040160405180910390fd5b50505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663afda13e96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3a9190613d82565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663689306376040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac0919061402e565b90506000612710612ad18486613dc4565b612adb9190613ddb565b9050612b0b7f00000000000000000000000000000000000000000000000000000000000000006107e58387613db1565b93508015612b3e57612b3e7f000000000000000000000000000000000000000000000000000000000000000083836128ee565b60008054612b5486670de0b6b3a7640000613dc4565b612b5e9190613ddb565b90508015612b7e5780600b6000828254612b789190613f7f565b90915550505b604080518681526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663afda13e96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c459190613d82565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663689306376040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccb919061402e565b90506000612710612cdc8486613dc4565b612ce69190613ddb565b9050612d167f00000000000000000000000000000000000000000000000000000000000000006107e58387613db1565b93508015612d4957612d497f000000000000000000000000000000000000000000000000000000000000000083836128ee565b60008054612d5f86670de0b6b3a7640000613dc4565b612d699190613ddb565b90508015612d895780600c6000828254612d839190613f7f565b90915550505b60408051600081526020810187905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612bb2565b60007f000000000000000000000000000000000000000000000000000000000000000015612ecb576000612df461338e565b612e0685670de0b6b3a7640000613dc4565b612e109190613ddb565b90506000612e1c613422565b612e2e85670de0b6b3a7640000613dc4565b612e389190613ddb565b90506000670de0b6b3a7640000612e4f8385613dc4565b612e599190613ddb565b90506000670de0b6b3a7640000612e708480613dc4565b612e7a9190613ddb565b670de0b6b3a7640000612e8d8680613dc4565b612e979190613ddb565b612ea19190613f7f565b9050670de0b6b3a7640000612eb68284613dc4565b612ec09190613ddb565b94505050505061112b565b612ed58284613dc4565b905061112b565b6008544290600090612eee9083613db1565b9050600081118015612eff57508315155b8015612f0a57508215155b15612f5157612f198185613dc4565b60096000828254612f2a9190613f7f565b90915550612f3a90508184613dc4565b600a6000828254612f4b9190613f7f565b90915550505b6000612f5b611dbe565b8051909150612f6a9084613db1565b915061070882111561301f576040805160608101825284815260095460208201908152600a549282019283526005805460018101825560009190915291517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0600390930292830155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db182015590517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2909101555b60068790556007869055600883905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000001561325c5760006130a48484612dc2565b90506130ae61338e565b6130c085670de0b6b3a7640000613dc4565b6130ca9190613ddb565b93506130d4613422565b6130e684670de0b6b3a7640000613dc4565b6130f09190613ddb565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614613135578486613138565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161461319e5761317d613422565b61318f89670de0b6b3a7640000613dc4565b6131999190613ddb565b6131c2565b6131a661338e565b6131b889670de0b6b3a7640000613dc4565b6131c29190613ddb565b975060006131da6131d3848b613f7f565b8584613784565b6131e49083613db1565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b0316146132355761323061338e565b61323d565b61323d613422565b6132479083613dc4565b6132519190613ddb565b945050505050611331565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161461329f5783856132a2565b84845b90925090506132b18783613f7f565b6132bb8289613dc4565b6132c59190613ddb565b92505050611331565b6132d78361359a565b6132e08261359a565b6001600160a01b03831660009081526002602052604081208054839290613308908490613db1565b90915550506001600160a01b03821660009081526002602052604081208054839290613335908490613f7f565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161338191815260200190565b60405180910390a3505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613412919061404b565b61341d90600a61414c565b905090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ee573d6000803e3d6000fd5b600060038211156134e3575080600061349c600283613ddb565b6134a7906001613f7f565b90505b818110156134dd579050806002816134c28186613ddb565b6134cc9190613f7f565b6134d69190613ddb565b90506134aa565b50919050565b81156134ed575060015b919050565b6134fb8261359a565b8060008082825461350c9190613f7f565b90915550506001600160a01b03821660009081526002602052604081208054839290613539908490613f7f565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310613593578161146a565b5090919050565b6001600160a01b03811660009081526002602052604090205480156136c8576001600160a01b0382166000908152600d602090815260408083208054600e8085529285208054600b54600c549481905594909552829055936135fc8584613db1565b9050600061360a8584613db1565b90508115613665576000670de0b6b3a7640000613627848a613dc4565b6136319190613ddb565b6001600160a01b038a166000908152600f602052604081208054929350839290919061365e908490613f7f565b9091555050505b80156136be576000670de0b6b3a7640000613680838a613dc4565b61368a9190613ddb565b6001600160a01b038a166000908152601060205260408120805492935083929091906136b7908490613f7f565b9091555050505b5050505050505050565b600b546001600160a01b0383166000908152600d6020908152604080832093909355600c54600e909152919020555050565b6137038261359a565b806000808282546137149190613db1565b90915550506001600160a01b03821660009081526002602052604081208054839290613741908490613db1565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001613578565b6000805b60ff81101561388a5782600061379e8783613893565b9050858110156137ee5760006137b48887613930565b6137be8389613db1565b6137d090670de0b6b3a7640000613dc4565b6137da9190613ddb565b90506137e68187613f7f565b955050613830565b60006137fa8887613930565b6138048884613db1565b61381690670de0b6b3a7640000613dc4565b6138209190613ddb565b905061382c8187613db1565b9550505b818511156138595760016138448387613db1565b116138545784935050505061146a565b613875565b60016138658684613db1565b116138755784935050505061146a565b5050808061388290614015565b915050613788565b50909392505050565b6000670de0b6b3a7640000828185816138ac8280613dc4565b6138b69190613ddb565b6138c09190613dc4565b6138ca9190613ddb565b6138d49190613dc4565b6138de9190613ddb565b670de0b6b3a76400008084816138f48280613dc4565b6138fe9190613ddb565b6139089190613dc4565b6139129190613ddb565b61391c9086613dc4565b6139269190613ddb565b61146a9190613f7f565b6000670de0b6b3a764000083816139478280613dc4565b6139519190613ddb565b61395b9190613dc4565b6139659190613ddb565b670de0b6b3a7640000806139798580613dc4565b6139839190613ddb565b61398e866003613dc4565b61391c9190613dc4565b6001600160a01b03811681146139ad57600080fd5b50565b6000806000806000608086880312156139c857600080fd5b853594506020860135935060408601356139e181613998565b9250606086013567ffffffffffffffff808211156139fe57600080fd5b818801915088601f830112613a1257600080fd5b813581811115613a2157600080fd5b896020828501011115613a3357600080fd5b9699959850939650602001949392505050565b60005b83811015613a61578181015183820152602001613a49565b50506000910152565b6020815260008251806020840152613a89816040850160208701613a46565b601f01601f19169190910160400192915050565b60008060408385031215613ab057600080fd5b8235613abb81613998565b946020939093013593505050565b60008060008060808587031215613adf57600080fd5b8435613aea81613998565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b81811015613b3c57835183529284019291840191600101613b20565b50909695505050505050565b600060208284031215613b5a57600080fd5b813561146a81613998565b600080600060608486031215613b7a57600080fd5b8335613b8581613998565b92506020840135613b9581613998565b929592945050506040919091013590565b600060208284031215613bb857600080fd5b5035919050565b600080600060608486031215613bd457600080fd5b8335613bdf81613998565b95602085013595506040909401359392505050565b600080600060608486031215613c0957600080fd5b833592506020840135613c1b81613998565b91506040840135613c2b81613998565b809150509250925092565b60ff811681146139ad57600080fd5b600080600080600080600060e0888a031215613c6057600080fd5b8735613c6b81613998565b96506020880135613c7b81613998565b955060408801359450606088013593506080880135613c9981613c36565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613cc957600080fd5b8235613cd481613998565b91506020830135613ce481613998565b809150509250929050565b60008060408385031215613d0257600080fd5b823591506020830135613ce481613998565b600060208284031215613d2657600080fd5b8151801515811461146a57600080fd5b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215613d9457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561112b5761112b613d9b565b808202811582820484141761112b5761112b613d9b565b600082613df857634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b600060208284031215613e2557600080fd5b815167ffffffffffffffff80821115613e3d57600080fd5b818401915084601f830112613e5157600080fd5b815181811115613e6357613e63613dfd565b604051601f8201601f19908116603f01168101908382118183101715613e8b57613e8b613dfd565b81604052828152876020848701011115613ea457600080fd5b611701836020830160208801613a46565b7f4c65657453776170563220537461626c6556312050616972202d200000000000815260008351613eed81601b850160208801613a46565b602f60f81b601b918401918201528351613f0e81601c840160208801613a46565b01601c01949350505050565b7f4c65657453776170563220566f6c6174696c6556312050616972202d20000000815260008351613f5281601d850160208801613a46565b602f60f81b601d918401918201528351613f7381601e840160208801613a46565b01601e01949350505050565b8082018082111561112b5761112b613d9b565b634e487b7160e01b600052603260045260246000fd5b64734c53322d60d81b815260008351613fc8816005850160208801613a46565b602f60f81b6005918401918201528351613fe9816006840160208801613a46565b01600601949350505050565b64764c53322d60d81b815260008351613fc8816005850160208801613a46565b60006001820161402757614027613d9b565b5060010190565b60006020828403121561404057600080fd5b815161146a81613998565b60006020828403121561405d57600080fd5b815161146a81613c36565b600181815b808511156140a357816000190482111561408957614089613d9b565b8085161561409657918102915b93841c939080029061406d565b509250929050565b6000826140ba5750600161112b565b816140c75750600061112b565b81600181146140dd57600281146140e757614103565b600191505061112b565b60ff8411156140f8576140f8613d9b565b50506001821b61112b565b5060208310610133831016604e8410600b8410161715614126575081810a61112b565b6141308383614068565b806000190482111561414457614144613d9b565b029392505050565b600061146a60ff8416836140ab56fea264697066735822122004f589f9c0880cb44ed95321cb7c212c6b2b68fb2702bf4b81cc545a683cebf464736f6c6343000811003360e060405234801561001057600080fd5b5060405161032138038061032183398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c05161025c6100c5600039600060c9015260006098015260006050015261025c6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046101bc565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461008d576040516282b42960e81b815260040160405180910390fd5b81156100be576100be7f000000000000000000000000000000000000000000000000000000000000000084846100f4565b80156100ef576100ef7f000000000000000000000000000000000000000000000000000000000000000084836100f4565b505050565b826001600160a01b03163b60000361011f5760405163c1ab6dc160e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390526000919085169063a9059cbb906044016020604051808303816000875af1158015610172573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019691906101fd565b9050806101b6576040516312171d8360e31b815260040160405180910390fd5b50505050565b6000806000606084860312156101d157600080fd5b83356001600160a01b03811681146101e857600080fd5b95602085013595506040909401359392505050565b60006020828403121561020f57600080fd5b8151801515811461021f57600080fd5b939250505056fea2646970667358221220dc778242d15758937c23a3da526868d4daa725d62e0fc4e62840da8e0634038764736f6c63430008110033a26469706673582212208fb2b4d4f741ae9959b02cf9f295e86facdc5656da564c9542202f84fc9c4c8364736f6c63430008110033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001af5760003560e01c80638da5cb5b11620000f0578063bedb86fb11620000a3578063e5e31b13116200007a578063e5e31b1314620003c3578063e6a4390514620003e9578063eb13c4cf146200042c578063f2fde38b146200046557600080fd5b8063bedb86fb146200037e578063c9c653961462000395578063e12ab55914620003ac57600080fd5b80638da5cb5b146200030a5780639a7165e4146200031c5780639aab924814620003305780639fd0506d146200033a578063afda13e9146200034e578063b187bd26146200035857600080fd5b8063574f2ba3116200016657806368930637116200013d5780636893063714620002be578063715018a614620002d25780637a72f06f14620002dc57806382dfdce414620002f357600080fd5b8063574f2ba3146200024d5780635cf7310814620002605780636801cc30146200027757600080fd5b8063064c1a7714620001b4578063167a6f9014620001e55780631e3dd18b14620001f1578063288eb1a314620002085780632d88af4a146200021f57806340d1b27a1462000236575b600080fd5b600354620001c8906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001ef6200047c565b005b620001c86200020236600462000b11565b620004cb565b620001ef6200021936600462000b11565b620004f6565b620001ef6200023036600462000b41565b6200051b565b620001ef6200024736600462000b41565b62000568565b6008545b604051908152602001620001dc565b620002516200027136600462000b61565b62000594565b620001c86200028836600462000bb5565b6001600160a01b039283166000908152600660209081526040808320948616835293815283822092151582529190915220541690565b600554620001c8906001600160a01b031681565b620001ef62000648565b620001ef620002ed36600462000b41565b62000660565b620001c86200030436600462000bb5565b6200068c565b6000546001600160a01b0316620001c8565b600254620001c8906001600160a01b031681565b6200025162000938565b600154620001c8906001600160a01b031681565b6200025160045481565b6000546200036d90600160a01b900460ff1681565b6040519015158152602001620001dc565b620001ef6200038f36600462000c03565b6200096c565b620001c8620003a636600462000b61565b620009b5565b620001ef620003bd36600462000b11565b620009c5565b6200036d620003d436600462000b41565b60096020526000908152604090205460ff1681565b620001c8620003fa36600462000b61565b6001600160a01b0391821660009081526006602090815260408083209385168352928152828220828052905220541690565b600a54600b54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff16151590820152606001620001dc565b620001ef6200047636600462000b41565b620009d4565b6002546001600160a01b03163314620004a7576040516282b42960e81b815260040160405180910390fd5b600254600180546001600160a01b0319166001600160a01b03909216919091179055565b60088181548110620004dc57600080fd5b6000918252602090912001546001600160a01b0316905081565b6200050062000a57565b611388811162000511578062000515565b6113885b60045550565b6001546001600160a01b0316331462000546576040516282b42960e81b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6200057262000a57565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6003546000906001600160a01b0316620005b257506007546200062e565b60035460405163ab898da760e01b81526001600160a01b03858116600483015284811660248301529091169063ab898da790604401602060405180830381865afa15801562000605573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200062b919062000c21565b90505b606481116200063e578062000641565b60645b9392505050565b6200065262000a57565b6200065e600062000ab3565b565b6200066a62000a57565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000826001600160a01b0316846001600160a01b031603620006c15760405163065af08d60e01b815260040160405180910390fd5b600080846001600160a01b0316866001600160a01b031610620006e6578486620006e9565b85855b90925090506001600160a01b038216620007165760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03828116600090815260066020908152604080832085851684528252808320881515845290915290205416156200076757604051633d77e89160e01b815260040160405180910390fd5b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600b80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600a805492881692909116919091179055915081906200080e9062000b03565b8190604051809103906000f59050801580156200082f573d6000803e3d6000fd5b506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560088054600181810183557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39091018054909a1687179099558587526009855295839020805460ff1916909817909755935481519687529186019290925290840152929650907fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a35050509392505050565b6000604051806020016200094c9062000b03565b6020820181038252601f19601f8201166040525080519060200120905090565b6001546001600160a01b0316331462000997576040516282b42960e81b815260040160405180910390fd5b60008054911515600160a01b0260ff60a01b19909216919091179055565b600062000641838360006200068c565b620009cf62000a57565b600755565b620009de62000a57565b6001600160a01b03811662000a495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b62000a548162000ab3565b50565b6000546001600160a01b031633146200065e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000a40565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61489a8062000c3c83390190565b60006020828403121562000b2457600080fd5b5035919050565b6001600160a01b038116811462000a5457600080fd5b60006020828403121562000b5457600080fd5b8135620006418162000b2b565b6000806040838503121562000b7557600080fd5b823562000b828162000b2b565b9150602083013562000b948162000b2b565b809150509250929050565b8035801515811462000bb057600080fd5b919050565b60008060006060848603121562000bcb57600080fd5b833562000bd88162000b2b565b9250602084013562000bea8162000b2b565b915062000bfa6040850162000b9f565b90509250925092565b60006020828403121562000c1657600080fd5b620006418262000b9f565b60006020828403121562000c3457600080fd5b505191905056fe610120604052600080556000600b556000600c5560016011553480156200002557600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000085573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ab9190620001f3565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000de90620001c8565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000112573d6000803e3d6000fd5b506001600160a01b031660e05250506040805160608101825242815260006020820181815292820181815260058054600181018255925291517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db060039092029182015591517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db1830155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2909101555062000245565b610321806200457983390190565b80516001600160a01b0381168114620001ee57600080fd5b919050565b6000806000606084860312156200020957600080fd5b6200021484620001d6565b92506200022460208501620001d6565b9150604084015180151581146200023a57600080fd5b809150509250925092565b60805160a05160c05160e05161010051614191620003e8600039600081816107370152818161083201528181610c1701528181611665015281816129ba01528181612a4001528181612bc50152612c4b0152600081816105fa015281816119f70152818161264c015281816126cb015261270701526000818161064f015281816107670152818161095301528181610bf201528181610efe0152818161102f01528181611517015281816117ea01528181611b0f01528181611eee0152818161200b0152818161227f0152818161286901528181612ced01528181612d2301526134260152600081816103760152818161062a0152818161093201528181610bd001528181610e7801528181610fa9015281816114f40152818161175401528181611aed01528181611e6801528181611f850152818161225d015281816127e101528181612ae201528181612b18015281816130f70152818161313e015281816131f101528181613261015261339201526000818161041401528181610e52015281816114d101528181611e4201528181612dc6015261307401526141916000f3fe608060405234801561001057600080fd5b50600436106102f15760003560e01c806389afcb441161019d578063bf944dbc116100e9578063d294f093116100a2578063ebeb31db1161007c578063ebeb31db146107cf578063ec7e683d146107d7578063f140a35a146107ea578063fff6cae9146107fd57600080fd5b8063d294f09314610789578063d505accf14610791578063dd62ed3e146107a457600080fd5b8063bf944dbc14610718578063c245febc14610721578063c3192f141461072a578063c45a015514610732578063c5700a0214610759578063d21220a71461076257600080fd5b80639f767c8811610156578063a9059cbb11610130578063a9059cbb146106e0578063ba9a7a56146106f3578063bc25cf77146106fc578063bda39cad1461070f57600080fd5b80639f767c881461068d578063a1ac4d13146106ad578063a88684b0146106cd57600080fd5b806389afcb44146105b05780638a7b8cf2146105c357806395d89b41146105ed5780639af1d35a146105f55780639d63848a1461061c5780639e8cc04b1461067a57600080fd5b8063313ce5671161025c5780635881c475116102155780636a627842116101ef5780636a6278421461053557806370a082311461054857806374522292146105685780637ecebe001461059057600080fd5b80635881c475146105065780635a76f25e146105195780635e1e63251461052257600080fd5b8063313ce5671461045c57806332c0defd14610476578063392f37e91461047f578063443cb4bc146104ca5780634d5a9f8a146104d3578063517b3f82146104f357600080fd5b806318160ddd116102ae57806318160ddd146103d05780631df8c717146103e7578063205aabf1146103ef57806322be3de11461040f57806323b872dd14610436578063252c09d71461044957600080fd5b8063022c0d9f146102f657806306fdde031461030b5780630902f1ac14610329578063095ea7b31461034e5780630dfe16811461037157806313345fe1146103b0575b600080fd5b6103096103043660046139b0565b610805565b005b610313610e4e565b6040516103209190613a6a565b60405180910390f35b6006546007546008545b60408051938452602084019290925290820152606001610320565b61036161035c366004613a9d565b6110c4565b6040519015158152602001610320565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610320565b6103c36103be366004613ac9565b611131565b6040516103209190613b04565b6103d960005481565b604051908152602001610320565b610333611339565b6103d96103fd366004613b48565b600e6020526000908152604090205481565b6103617f000000000000000000000000000000000000000000000000000000000000000081565b610361610444366004613b65565b6113a8565b610333610457366004613ba6565b611471565b610464601281565b60405160ff9091168152602001610320565b6103d9600b5481565b6104876114a4565b604080519788526020880196909652948601939093526060850191909152151560808401526001600160a01b0390811660a08401521660c082015260e001610320565b6103d960065481565b6103d96104e1366004613b48565b600f6020526000908152604090205481565b6103d9610501366004613a9d565b61153c565b6103c3610514366004613bbf565b611624565b6103d960075481565b6103d9610530366004613bf4565b611633565b6103d9610543366004613b48565b61170c565b6103d9610556366004613b48565b60026020526000908152604090205481565b61057b610576366004613b48565b61196b565b60408051928352602083019190915201610320565b6103d961059e366004613b48565b60046020526000908152604090205481565b61057b6105be366004613b48565b611aa7565b6105cb611dbe565b6040805182518152602080840151908201529181015190820152606001610320565b610313611e3e565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f000000000000000000000000000000000000000000000000000000000000000016602082015201610320565b6103d9610688366004613bbf565b6120a0565b6103d961069b366004613b48565b600d6020526000908152604090205481565b6103d96106bb366004613b48565b60106020526000908152604090205481565b61057b6106db366004613b48565b61210d565b6103616106ee366004613a9d565b612207565b6103d96103e881565b61030961070a366004613b48565b61221d565b6103d9600c5481565b6103d960095481565b6103d9600a5481565b61057b61234f565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b6103d960085481565b6103987f000000000000000000000000000000000000000000000000000000000000000081565b61057b612363565b61030961079f366004613c45565b61236f565b6103d96107b2366004613cb6565b600160209081526000928352604080842090915290825290205481565b6005546103d9565b6103d96107e5366004613a9d565b612623565b6103d96107f8366004613cef565b612793565b6103096127a0565b601154600114610828576040516345f5ce8b60e11b815260040160405180910390fd5b60026011819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa15801561088e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b29190613d14565b156108d057604051639153568960e01b815260040160405180910390fd5b841580156108dc575083155b156108fa576040516342301c2360e01b815260040160405180910390fd5b600654600754818710158061090f5750808610155b1561092d5760405163bb55fd2760e01b815260040160405180910390fd5b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148061099d5750806001600160a01b0316896001600160a01b0316145b156109bb5760405163d4f6398f60e01b815260040160405180910390fd5b8a156109cc576109cc828a8d6128ee565b89156109dd576109dd818a8c6128ee565b8615610a4a57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff7990610a179033908f908f908e908e90600401613d36565b600060405180830381600087803b158015610a3157600080fd5b505af1158015610a45573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab29190613d82565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d9190613d82565b9250505060008985610b2f9190613db1565b8311610b3c576000610b50565b610b468a86613db1565b610b509084613db1565b90506000610b5e8a86613db1565b8311610b6b576000610b7f565b610b758a86613db1565b610b7f9084613db1565b905081158015610b8d575080155b15610bab5760405163098fb56160e01b815260040160405180910390fd5b604051630b9ee62160e31b81523060048201526001600160a01b038a811660248301527f0000000000000000000000000000000000000000000000000000000000000000917f0000000000000000000000000000000000000000000000000000000000000000916000917f000000000000000000000000000000000000000000000000000000000000000090911690635cf7310890604401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c849190613d82565b90508415610cab57610cab612710610c9c8388613dc4565b610ca69190613ddb565b6129b6565b8315610cd057610cd0612710610cc18387613dc4565b610ccb9190613ddb565b612bc1565b6040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa158015610d14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d389190613d82565b6040516370a0823160e01b81523060048201529097506001600160a01b038316906370a0823190602401602060405180830381865afa158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190613d82565b9550610daf8989612dc2565b610db98888612dc2565b1015610dd857604051636458e09f60e11b815260040160405180910390fd5b505050610de784848888612edc565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601155505050505050505050565b60607f000000000000000000000000000000000000000000000000000000000000000015610fa7577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ed4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610efc9190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610f5a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f829190810190613e13565b604051602001610f93929190613eb5565b604051602081830303815290604052905090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611005573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261102d9190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561108b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b39190810190613e13565b604051602001610f93929190613f1a565b3360008181526001602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061111f9086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff81111561114e5761114e613dfd565b604051908082528060200260200182016040528015611177578160200160208202803683370190505b5060055490915060009061118d90600190613db1565b9050600061119b8587613dc4565b6111a59083613db1565b90506000805b83831015611329576111bd8784613f7f565b91506000600584815481106111d4576111d4613f92565b906000526020600020906003020160000154600584815481106111f9576111f9613f92565b9060005260206000209060030201600001546112159190613db1565b90506000816005868154811061122d5761122d613f92565b9060005260206000209060030201600101546005868154811061125257611252613f92565b90600052602060002090600302016001015461126e9190613db1565b6112789190613ddb565b90506000826005878154811061129057611290613f92565b906000526020600020906003020160020154600587815481106112b5576112b5613f92565b9060005260206000209060030201600201546112d19190613db1565b6112db9190613ddb565b90506112e98c8e8484613070565b8885815181106112fb576112fb613f92565b6020908102919091010152611311846001613f7f565b935050505086836113229190613f7f565b92506111ab565b509293505050505b949350505050565b600954600a5442600080806113576006546007546008549192909190565b9250925092508381146113a05760006113708286613db1565b905061137c8185613dc4565b6113869088613f7f565b96506113928184613dc4565b61139c9087613f7f565b9550505b505050909192565b6001600160a01b0383166000818152600160209081526040808320338085529252822054919290919082148015906113e257506000198114155b156114585760006113f38583613db1565b6001600160a01b038881166000818152600160209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6114638686866132ce565b6001925050505b9392505050565b6005818154811061148157600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b60008060008060008060006114b761338e565b6114bf613422565b600654600754929a91995097509095507f000000000000000000000000000000000000000000000000000000000000000094507f000000000000000000000000000000000000000000000000000000000000000093507f000000000000000000000000000000000000000000000000000000000000000092509050565b600080611547611dbe565b9050600080611554611339565b508451919350915042036115bc576005805461157290600290613db1565b8154811061158257611582613f92565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906115cb9042613db1565b90506000818560200151856115e09190613db1565b6115ea9190613ddb565b90506000828660400151856115ff9190613db1565b6116099190613ddb565b9050611617888a8484613070565b9998505050505050505050565b60606113318484846001611131565b600654600754604051630b9ee62160e31b81523060048201526001600160a01b038481166024830152600093929184917f00000000000000000000000000000000000000000000000000000000000000001690635cf7310890604401602060405180830381865afa1580156116ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d09190613d82565b90506127106116df8289613dc4565b6116e99190613ddb565b6116f39088613db1565b965061170187878585613070565b979650505050505050565b6000601154600114611731576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556006546007546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156117a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c79190613d82565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611831573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118559190613d82565b905060006118638584613db1565b905060006118718584613db1565b600080549192508190036118b2576103e861189461188f8486613dc4565b613482565b61189e9190613db1565b97506118ad60006103e86134f2565b6118e7565b6118e4876118c08386613dc4565b6118ca9190613ddb565b876118d58486613dc4565b6118df9190613ddb565b613584565b97505b6000881161190857604051633489be7560e21b815260040160405180910390fd5b61191289896134f2565b61191e85858989612edc565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601155509395945050505050565b600080601154600114611991576040516345f5ce8b60e11b815260040160405180910390fd5b600260115561199f8361359a565b50506001600160a01b038181166000818152600f6020908152604080832080546010909352818420805491859055939093555163299e7ae760e11b8152600481019390935260248301819052604483018290529290917f00000000000000000000000000000000000000000000000000000000000000009091169063533cf5ce90606401600060405180830381600087803b158015611a3d57600080fd5b505af1158015611a51573d6000803e3d6000fd5b505060408051858152602081018590526001600160a01b03871693503392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a360016011559092909150565b600080601154600114611acd576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556006546007546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b879190613d82565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611bd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf59190613d82565b3060009081526002602052604081205490549192509080611c168584613dc4565b611c209190613ddb565b995080611c2d8484613dc4565b611c379190613ddb565b9850891580611c44575088155b15611c625760405163749383ad60e01b815260040160405180910390fd5b611c6c30836136fa565b611c77868c8c6128ee565b611c82858c8b6128ee565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cea9190613d82565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d559190613d82565b9250611d6384848a8a612edc565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601181905550915091565b611de260405180606001604052806000815260200160008152602001600081525090565b60058054611df290600190613db1565b81548110611e0257611e02613f92565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60607f000000000000000000000000000000000000000000000000000000000000000015611f83577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611ec4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611eec9190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611f4a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f729190810190613e13565b604051602001610f93929190613fa8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611fe1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120099190810190613e13565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612067573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261208f9190810190613e13565b604051602001610f93929190613ff5565b6000806120b08585856001611131565b90506000805b82518110156120f8578281815181106120d1576120d1613f92565b6020026020010151826120e49190613f7f565b9150806120f081614015565b9150506120b6565b506121038482613ddb565b9695505050505050565b6001600160a01b038116600090815260026020908152604080832054600f835281842054601090935292205490918015612201576001600160a01b0384166000908152600d6020526040812054600b546121679190613db1565b6001600160a01b0386166000908152600e6020526040812054600c5492935090916121929190613db1565b905081156121c9576000670de0b6b3a76400006121af8486613dc4565b6121b99190613ddb565b90506121c58187613f7f565b9550505b80156121fe576000670de0b6b3a76400006121e48386613dc4565b6121ee9190613ddb565b90506121fa8186613f7f565b9450505b50505b50915091565b60006122143384846132ce565b50600192915050565b601154600114612240576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556006546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f00000000000000000000000000000000000000000000000000000000000000009161230d9184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa1580156122da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122fe9190613d82565b6123089190613db1565b6128ee565b6007546040516370a0823160e01b81523060048201526123459183918691906001600160a01b038416906370a08231906024016122bd565b5050600160115550565b60008061235b3361210d565b915091509091565b60008061235b3361196b565b4284101561239057604051631ab7da6b60e01b815260040160405180910390fd5b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6123b9610e4e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060038190556001600160a01b038a166000908152600490935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761248583614015565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e001604051602081830303815290604052805190602001206040516020016124fe92919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015612569573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158061259e5750886001600160a01b0316816001600160a01b031614155b156125bc57604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b038981166000818152600160209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b6000816000036126355750600061112b565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600091908516906370a0823190602401602060405180830381865afa15801561269f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c39190613d82565b90506126f0847f0000000000000000000000000000000000000000000000000000000000000000856128ee565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600091908616906370a0823190602401602060405180830381865afa15801561275a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277e9190613d82565b905061278a8282613db1565b95945050505050565b600061146a838333611633565b6011546001146127c3576040516345f5ce8b60e11b815260040160405180910390fd5b60026011556040516370a0823160e01b81523060048201526128e7907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612830573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128549190613d82565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156128b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128dc9190613d82565b600654600754612edc565b6001601155565b826001600160a01b03163b6000036129195760405163c1ab6dc160e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390526000919085169063a9059cbb906044016020604051808303816000875af115801561296c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129909190613d14565b9050806129b0576040516312171d8360e31b815260040160405180910390fd5b50505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663afda13e96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3a9190613d82565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663689306376040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac0919061402e565b90506000612710612ad18486613dc4565b612adb9190613ddb565b9050612b0b7f00000000000000000000000000000000000000000000000000000000000000006107e58387613db1565b93508015612b3e57612b3e7f000000000000000000000000000000000000000000000000000000000000000083836128ee565b60008054612b5486670de0b6b3a7640000613dc4565b612b5e9190613ddb565b90508015612b7e5780600b6000828254612b789190613f7f565b90915550505b604080518681526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663afda13e96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c459190613d82565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663689306376040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccb919061402e565b90506000612710612cdc8486613dc4565b612ce69190613ddb565b9050612d167f00000000000000000000000000000000000000000000000000000000000000006107e58387613db1565b93508015612d4957612d497f000000000000000000000000000000000000000000000000000000000000000083836128ee565b60008054612d5f86670de0b6b3a7640000613dc4565b612d699190613ddb565b90508015612d895780600c6000828254612d839190613f7f565b90915550505b60408051600081526020810187905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612bb2565b60007f000000000000000000000000000000000000000000000000000000000000000015612ecb576000612df461338e565b612e0685670de0b6b3a7640000613dc4565b612e109190613ddb565b90506000612e1c613422565b612e2e85670de0b6b3a7640000613dc4565b612e389190613ddb565b90506000670de0b6b3a7640000612e4f8385613dc4565b612e599190613ddb565b90506000670de0b6b3a7640000612e708480613dc4565b612e7a9190613ddb565b670de0b6b3a7640000612e8d8680613dc4565b612e979190613ddb565b612ea19190613f7f565b9050670de0b6b3a7640000612eb68284613dc4565b612ec09190613ddb565b94505050505061112b565b612ed58284613dc4565b905061112b565b6008544290600090612eee9083613db1565b9050600081118015612eff57508315155b8015612f0a57508215155b15612f5157612f198185613dc4565b60096000828254612f2a9190613f7f565b90915550612f3a90508184613dc4565b600a6000828254612f4b9190613f7f565b90915550505b6000612f5b611dbe565b8051909150612f6a9084613db1565b915061070882111561301f576040805160608101825284815260095460208201908152600a549282019283526005805460018101825560009190915291517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0600390930292830155517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db182015590517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2909101555b60068790556007869055600883905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000001561325c5760006130a48484612dc2565b90506130ae61338e565b6130c085670de0b6b3a7640000613dc4565b6130ca9190613ddb565b93506130d4613422565b6130e684670de0b6b3a7640000613dc4565b6130f09190613ddb565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614613135578486613138565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161461319e5761317d613422565b61318f89670de0b6b3a7640000613dc4565b6131999190613ddb565b6131c2565b6131a661338e565b6131b889670de0b6b3a7640000613dc4565b6131c29190613ddb565b975060006131da6131d3848b613f7f565b8584613784565b6131e49083613db1565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b0316146132355761323061338e565b61323d565b61323d613422565b6132479083613dc4565b6132519190613ddb565b945050505050611331565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161461329f5783856132a2565b84845b90925090506132b18783613f7f565b6132bb8289613dc4565b6132c59190613ddb565b92505050611331565b6132d78361359a565b6132e08261359a565b6001600160a01b03831660009081526002602052604081208054839290613308908490613db1565b90915550506001600160a01b03821660009081526002602052604081208054839290613335908490613f7f565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161338191815260200190565b60405180910390a3505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613412919061404b565b61341d90600a61414c565b905090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ee573d6000803e3d6000fd5b600060038211156134e3575080600061349c600283613ddb565b6134a7906001613f7f565b90505b818110156134dd579050806002816134c28186613ddb565b6134cc9190613f7f565b6134d69190613ddb565b90506134aa565b50919050565b81156134ed575060015b919050565b6134fb8261359a565b8060008082825461350c9190613f7f565b90915550506001600160a01b03821660009081526002602052604081208054839290613539908490613f7f565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310613593578161146a565b5090919050565b6001600160a01b03811660009081526002602052604090205480156136c8576001600160a01b0382166000908152600d602090815260408083208054600e8085529285208054600b54600c549481905594909552829055936135fc8584613db1565b9050600061360a8584613db1565b90508115613665576000670de0b6b3a7640000613627848a613dc4565b6136319190613ddb565b6001600160a01b038a166000908152600f602052604081208054929350839290919061365e908490613f7f565b9091555050505b80156136be576000670de0b6b3a7640000613680838a613dc4565b61368a9190613ddb565b6001600160a01b038a166000908152601060205260408120805492935083929091906136b7908490613f7f565b9091555050505b5050505050505050565b600b546001600160a01b0383166000908152600d6020908152604080832093909355600c54600e909152919020555050565b6137038261359a565b806000808282546137149190613db1565b90915550506001600160a01b03821660009081526002602052604081208054839290613741908490613db1565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001613578565b6000805b60ff81101561388a5782600061379e8783613893565b9050858110156137ee5760006137b48887613930565b6137be8389613db1565b6137d090670de0b6b3a7640000613dc4565b6137da9190613ddb565b90506137e68187613f7f565b955050613830565b60006137fa8887613930565b6138048884613db1565b61381690670de0b6b3a7640000613dc4565b6138209190613ddb565b905061382c8187613db1565b9550505b818511156138595760016138448387613db1565b116138545784935050505061146a565b613875565b60016138658684613db1565b116138755784935050505061146a565b5050808061388290614015565b915050613788565b50909392505050565b6000670de0b6b3a7640000828185816138ac8280613dc4565b6138b69190613ddb565b6138c09190613dc4565b6138ca9190613ddb565b6138d49190613dc4565b6138de9190613ddb565b670de0b6b3a76400008084816138f48280613dc4565b6138fe9190613ddb565b6139089190613dc4565b6139129190613ddb565b61391c9086613dc4565b6139269190613ddb565b61146a9190613f7f565b6000670de0b6b3a764000083816139478280613dc4565b6139519190613ddb565b61395b9190613dc4565b6139659190613ddb565b670de0b6b3a7640000806139798580613dc4565b6139839190613ddb565b61398e866003613dc4565b61391c9190613dc4565b6001600160a01b03811681146139ad57600080fd5b50565b6000806000806000608086880312156139c857600080fd5b853594506020860135935060408601356139e181613998565b9250606086013567ffffffffffffffff808211156139fe57600080fd5b818801915088601f830112613a1257600080fd5b813581811115613a2157600080fd5b896020828501011115613a3357600080fd5b9699959850939650602001949392505050565b60005b83811015613a61578181015183820152602001613a49565b50506000910152565b6020815260008251806020840152613a89816040850160208701613a46565b601f01601f19169190910160400192915050565b60008060408385031215613ab057600080fd5b8235613abb81613998565b946020939093013593505050565b60008060008060808587031215613adf57600080fd5b8435613aea81613998565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b81811015613b3c57835183529284019291840191600101613b20565b50909695505050505050565b600060208284031215613b5a57600080fd5b813561146a81613998565b600080600060608486031215613b7a57600080fd5b8335613b8581613998565b92506020840135613b9581613998565b929592945050506040919091013590565b600060208284031215613bb857600080fd5b5035919050565b600080600060608486031215613bd457600080fd5b8335613bdf81613998565b95602085013595506040909401359392505050565b600080600060608486031215613c0957600080fd5b833592506020840135613c1b81613998565b91506040840135613c2b81613998565b809150509250925092565b60ff811681146139ad57600080fd5b600080600080600080600060e0888a031215613c6057600080fd5b8735613c6b81613998565b96506020880135613c7b81613998565b955060408801359450606088013593506080880135613c9981613c36565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613cc957600080fd5b8235613cd481613998565b91506020830135613ce481613998565b809150509250929050565b60008060408385031215613d0257600080fd5b823591506020830135613ce481613998565b600060208284031215613d2657600080fd5b8151801515811461146a57600080fd5b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215613d9457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561112b5761112b613d9b565b808202811582820484141761112b5761112b613d9b565b600082613df857634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b600060208284031215613e2557600080fd5b815167ffffffffffffffff80821115613e3d57600080fd5b818401915084601f830112613e5157600080fd5b815181811115613e6357613e63613dfd565b604051601f8201601f19908116603f01168101908382118183101715613e8b57613e8b613dfd565b81604052828152876020848701011115613ea457600080fd5b611701836020830160208801613a46565b7f4c65657453776170563220537461626c6556312050616972202d200000000000815260008351613eed81601b850160208801613a46565b602f60f81b601b918401918201528351613f0e81601c840160208801613a46565b01601c01949350505050565b7f4c65657453776170563220566f6c6174696c6556312050616972202d20000000815260008351613f5281601d850160208801613a46565b602f60f81b601d918401918201528351613f7381601e840160208801613a46565b01601e01949350505050565b8082018082111561112b5761112b613d9b565b634e487b7160e01b600052603260045260246000fd5b64734c53322d60d81b815260008351613fc8816005850160208801613a46565b602f60f81b6005918401918201528351613fe9816006840160208801613a46565b01600601949350505050565b64764c53322d60d81b815260008351613fc8816005850160208801613a46565b60006001820161402757614027613d9b565b5060010190565b60006020828403121561404057600080fd5b815161146a81613998565b60006020828403121561405d57600080fd5b815161146a81613c36565b600181815b808511156140a357816000190482111561408957614089613d9b565b8085161561409657918102915b93841c939080029061406d565b509250929050565b6000826140ba5750600161112b565b816140c75750600061112b565b81600181146140dd57600281146140e757614103565b600191505061112b565b60ff8411156140f8576140f8613d9b565b50506001821b61112b565b5060208310610133831016604e8410600b8410161715614126575081810a61112b565b6141308383614068565b806000190482111561414457614144613d9b565b029392505050565b600061146a60ff8416836140ab56fea264697066735822122004f589f9c0880cb44ed95321cb7c212c6b2b68fb2702bf4b81cc545a683cebf464736f6c6343000811003360e060405234801561001057600080fd5b5060405161032138038061032183398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c05161025c6100c5600039600060c9015260006098015260006050015261025c6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046101bc565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461008d576040516282b42960e81b815260040160405180910390fd5b81156100be576100be7f000000000000000000000000000000000000000000000000000000000000000084846100f4565b80156100ef576100ef7f000000000000000000000000000000000000000000000000000000000000000084836100f4565b505050565b826001600160a01b03163b60000361011f5760405163c1ab6dc160e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390526000919085169063a9059cbb906044016020604051808303816000875af1158015610172573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019691906101fd565b9050806101b6576040516312171d8360e31b815260040160405180910390fd5b50505050565b6000806000606084860312156101d157600080fd5b83356001600160a01b03811681146101e857600080fd5b95602085013595506040909401359392505050565b60006020828403121561020f57600080fd5b8151801515811461021f57600080fd5b939250505056fea2646970667358221220dc778242d15758937c23a3da526868d4daa725d62e0fc4e62840da8e0634038764736f6c63430008110033a26469706673582212208fb2b4d4f741ae9959b02cf9f295e86facdc5656da564c9542202f84fc9c4c8364736f6c63430008110033
Deployed Bytecode Sourcemap
188:4599:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;339:43;;;;;-1:-1:-1;;;;;339:43:4;;;;;;-1:-1:-1;;;;;205:32:12;;;187:51;;175:2;160:18;339:43:4;;;;;;;;1558:136;;;:::i;:::-;;601:25;;;;;;:::i;:::-;;:::i;4563:222::-;;;;;;:::i;:::-;;:::i;1410:142::-;;;;;;:::i;:::-;;:::i;4121:163::-;;;;;;:::i;:::-;;:::i;1307:97::-;1382:8;:15;1307:97;;;1455:25:12;;;1443:2;1428:18;1307:97:4;1309:177:12;3728:354:4;;;;;;:::i;:::-;;:::i;2169:189::-;;;;;;:::i;:::-;-1:-1:-1;;;;;2319:16:4;;;2293:7;2319:16;;;:8;:16;;;;;;;;:24;;;;;;;;;;;:32;;;;;;;;;;;;;2169:189;426:36;;;;;-1:-1:-1;;;;;426:36:4;;;1831:101:0;;;:::i;4290:168:4:-;;;;;;:::i;:::-;;:::i;2560:969::-;;;;;;:::i;:::-;;:::i;1201:85:0:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:0;1201:85;;305:28:4;;;;;-1:-1:-1;;;;;305:28:4;;;1837:124;;;:::i;278:21::-;;;;;-1:-1:-1;;;;;278:21:4;;;388:32;;;;;;252:20;;;;;-1:-1:-1;;;252:20:4;;;;;;;;;2857:14:12;;2850:22;2832:41;;2820:2;2805:18;252:20:4;2692:187:12;1700:131:4;;;;;;:::i;:::-;;:::i;3561:161::-;;;;;;:::i;:::-;;:::i;4464:93::-;;;;;;:::i;:::-;;:::i;632:38::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;2390:164;;;;;;:::i;:::-;-1:-1:-1;;;;;2516:16:4;;;2486:7;2516:16;;;:8;:16;;;;;;;;:24;;;;;;;;;;;:31;;;;;;;;;2390:164;1967:196;2134:6;;2142;;1967:196;;;-1:-1:-1;;;;;2134:6:4;;;3303:34:12;;2142:6:4;;;3368:2:12;3353:18;;3346:43;-1:-1:-1;;;2150:5:4;;;;;3432:14:12;3425:22;3405:18;;;3398:50;3253:2;3238:18;1967:196:4;3069:385:12;2081:198:0;;;;;;:::i;:::-;;:::i;1558:136:4:-;1619:13;;-1:-1:-1;;;;;1619:13:4;1605:10;:27;1601:54;;1641:14;;-1:-1:-1;;;1641:14:4;;;;;;;;;;;1601:54;1674:13;;;1665:22;;-1:-1:-1;;;;;;1665:22:4;-1:-1:-1;;;;;1674:13:4;;;1665:22;;;;;;1558:136::o;601:25::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;601:25:4;;-1:-1:-1;601:25:4;:::o;4563:222::-;1094:13:0;:11;:13::i;:::-;4711:4:4::1;4690:18;:25;:77;;4749:18;4690:77;;;4730:4;4690:77;4670:17;:97:::0;-1:-1:-1;4563:222:4:o;1410:142::-;1483:6;;-1:-1:-1;;;;;1483:6:4;1469:10;:20;1465:47;;1498:14;;-1:-1:-1;;;1498:14:4;;;;;;;;;;;1465:47;1522:13;:23;;-1:-1:-1;;;;;;1522:23:4;-1:-1:-1;;;;;1522:23:4;;;;;;;;;;1410:142::o;4121:163::-;1094:13:0;:11;:13::i;:::-;4239:17:4::1;:38:::0;;-1:-1:-1;;;;;;4239:38:4::1;-1:-1:-1::0;;;;;4239:38:4;;;::::1;::::0;;;::::1;::::0;;4121:163::o;3728:354::-;3862:17;;3822:12;;-1:-1:-1;;;;;3862:17:4;3850:170;;-1:-1:-1;3917:12:4;;3850:170;;;3967:17;;:42;;-1:-1:-1;;;3967:42:4;;-1:-1:-1;;;;;3689:15:12;;;3967:42:4;;;3671:34:12;3741:15;;;3721:18;;;3714:43;3967:17:4;;;;:32;;3606:18:12;;3967:42:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3960:49;;3850:170;4044:3;4037:4;:10;:23;;4056:4;4037:23;;;4050:3;4037:23;4030:30;3728:354;-1:-1:-1;;;3728:354:4:o;1831:101:0:-;1094:13;:11;:13::i;:::-;1895:30:::1;1922:1;1895:18;:30::i;:::-;1831:101::o:0;4290:168:4:-;1094:13:0;:11;:13::i;:::-;4405:21:4::1;:46:::0;;-1:-1:-1;;;;;;4405:46:4::1;-1:-1:-1::0;;;;;4405:46:4;;;::::1;::::0;;;::::1;::::0;;4290:168::o;2560:969::-;2671:12;2709:6;-1:-1:-1;;;;;2699:16:4;:6;-1:-1:-1;;;;;2699:16:4;;2695:47;;2724:18;;-1:-1:-1;;;2724:18:4;;;;;;;;;;;2695:47;2753:14;2769;2796:6;-1:-1:-1;;;;;2787:15:4;:6;-1:-1:-1;;;;;2787:15:4;;:77;;2849:6;2857;2787:77;;;2818:6;2826;2787:77;2752:112;;-1:-1:-1;2752:112:4;-1:-1:-1;;;;;;2878:20:4;;2874:46;;2907:13;;-1:-1:-1;;;2907:13:4;;;;;;;;;;;2874:46;-1:-1:-1;;;;;2934:16:4;;;2978:1;2934:16;;;:8;:16;;;;;;;;:24;;;;;;;;;;:32;;;;;;;;;;;;:46;2930:71;;2989:12;;-1:-1:-1;;;2989:12:4;;;;;;;;;;;2930:71;3036:40;;-1:-1:-1;;4206:2:12;4202:15;;;4198:24;;3036:40:4;;;4186:37:12;4257:15;;;4253:24;4239:12;;;4232:46;4324:14;;4317:22;4312:3;4308:32;4294:12;;;4287:54;3011:12:4;;4357::12;;3036:40:4;;;-1:-1:-1;;3036:40:4;;;;;;;;;;3026:51;;3036:40;3026:51;;;;3149:6;3140:50;;-1:-1:-1;;;;;3140:50:4;;;-1:-1:-1;;;;;;3140:50:4;;;-1:-1:-1;;;3140:50:4;;;-1:-1:-1;;;;;;3140:50:4;;;;;;;;;;;3141:6;3140:50;;;;;;;;;;;;;;;3026:51;-1:-1:-1;3026:51:4;;3215:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;3258:16:4;;;;;;;:8;:16;;;;;;;;:24;;;;;;;;;;;;:32;;;;;;;;;;;;:39;;;;;-1:-1:-1;;;;;;3258:39:4;;;;;;;;3307:16;;;;;;;;;:24;;;;;;;;:32;;;;;;;;:39;;;;;;;;3401:8;:19;;-1:-1:-1;3401:19:4;;;;;;;;;;;;;;;;;;;3430:12;;;:6;:12;;;;;;:19;;-1:-1:-1;;3430:19:4;;;;;;;3506:15;;3464:58;;4576:41:12;;;4633:18;;;4626:60;;;;4702:18;;;4695:34;3258:39:4;;-1:-1:-1;3258:16:4;3464:58;;4564:2:12;4549:18;3464:58:4;;;;;;;2685:844;;;2560:969;;;;;:::o;1837:124::-;1884:7;1920:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;1910:44;;;;;;1903:51;;1837:124;:::o;1700:131::-;1768:6;;-1:-1:-1;;;;;1768:6:4;1754:10;:20;1750:47;;1783:14;;-1:-1:-1;;;1783:14:4;;;;;;;;;;;1750:47;1807:8;:17;;;;;-1:-1:-1;;;1807:17:4;-1:-1:-1;;;;1807:17:4;;;;;;;;;1700:131::o;3561:161::-;3647:12;3682:33;3693:6;3701;3709:5;3682:10;:33::i;4464:93::-;1094:13:0;:11;:13::i;:::-;4531:12:4::1;:19:::0;4464:93::o;2081:198:0:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2169:22:0;::::1;2161:73;;;::::0;-1:-1:-1;;;2161:73:0;;4942:2:12;2161:73:0::1;::::0;::::1;4924:21:12::0;4981:2;4961:18;;;4954:30;5020:34;5000:18;;;4993:62;-1:-1:-1;;;5071:18:12;;;5064:36;5117:19;;2161:73:0::1;;;;;;;;;2244:28;2263:8;2244:18;:28::i;:::-;2081:198:::0;:::o;1359:130::-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:0;719:10:3;1422:23:0;1414:68;;;;-1:-1:-1;;;1414:68:0;;5349:2:12;1414:68:0;;;5331:21:12;;;5368:18;;;5361:30;5427:34;5407:18;;;5400:62;5479:18;;1414:68:0;5147:356:12;2433:187:0;2506:16;2525:6;;-1:-1:-1;;;;;2541:17:0;;;-1:-1:-1;;;;;;2541:17:0;;;;;;2573:40;;2525:6;;;;;;;2573:40;;2506:16;2573:40;2496:124;2433:187;:::o;-1:-1:-1:-;;;;;;;;:::o;249:180:12:-;308:6;361:2;349:9;340:7;336:23;332:32;329:52;;;377:1;374;367:12;329:52;-1:-1:-1;400:23:12;;249:180;-1:-1:-1;249:180:12:o;642:131::-;-1:-1:-1;;;;;717:31:12;;707:42;;697:70;;763:1;760;753:12;778:247;837:6;890:2;878:9;869:7;865:23;861:32;858:52;;;906:1;903;896:12;858:52;945:9;932:23;964:31;989:5;964:31;:::i;1491:388::-;1559:6;1567;1620:2;1608:9;1599:7;1595:23;1591:32;1588:52;;;1636:1;1633;1626:12;1588:52;1675:9;1662:23;1694:31;1719:5;1694:31;:::i;:::-;1744:5;-1:-1:-1;1801:2:12;1786:18;;1773:32;1814:33;1773:32;1814:33;:::i;:::-;1866:7;1856:17;;;1491:388;;;;;:::o;1884:160::-;1949:20;;2005:13;;1998:21;1988:32;;1978:60;;2034:1;2031;2024:12;1978:60;1884:160;;;:::o;2049:456::-;2123:6;2131;2139;2192:2;2180:9;2171:7;2167:23;2163:32;2160:52;;;2208:1;2205;2198:12;2160:52;2247:9;2234:23;2266:31;2291:5;2266:31;:::i;:::-;2316:5;-1:-1:-1;2373:2:12;2358:18;;2345:32;2386:33;2345:32;2386:33;:::i;:::-;2438:7;-1:-1:-1;2464:35:12;2495:2;2480:18;;2464:35;:::i;:::-;2454:45;;2049:456;;;;;:::o;2884:180::-;2940:6;2993:2;2981:9;2972:7;2968:23;2964:32;2961:52;;;3009:1;3006;2999:12;2961:52;3032:26;3048:9;3032:26;:::i;3768:184::-;3838:6;3891:2;3879:9;3870:7;3866:23;3862:32;3859:52;;;3907:1;3904;3897:12;3859:52;-1:-1:-1;3930:16:12;;3768:184;-1:-1:-1;3768:184:12:o
Swarm Source
ipfs://8fb2b4d4f741ae9959b02cf9f295e86facdc5656da564c9542202f84fc9c4c83
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.