More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 54,655 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap Exact Token... | 14999249 | 12 mins ago | IN | 0 frxETH | 0.00000044 | ||||
Swap Exact Token... | 14998515 | 37 mins ago | IN | 0 frxETH | 0.00000025 | ||||
Swap Exact Token... | 14998514 | 37 mins ago | IN | 0 frxETH | 0.00000025 | ||||
Swap Exact Token... | 14998380 | 41 mins ago | IN | 0 frxETH | 0.00000025 | ||||
Swap Exact Token... | 14995428 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14995411 | 2 hrs ago | IN | 0 frxETH | 0.00000041 | ||||
Swap Exact Token... | 14995407 | 2 hrs ago | IN | 0 frxETH | 0.00000041 | ||||
Swap Exact Token... | 14995403 | 2 hrs ago | IN | 0 frxETH | 0.00000041 | ||||
Swap Exact Token... | 14995387 | 2 hrs ago | IN | 0 frxETH | 0.00000041 | ||||
Swap Exact Token... | 14995301 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14995283 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14995229 | 2 hrs ago | IN | 0 frxETH | 0.00000041 | ||||
Swap Exact Token... | 14995220 | 2 hrs ago | IN | 0 frxETH | 0.00000025 | ||||
Swap Exact Token... | 14995219 | 2 hrs ago | IN | 0 frxETH | 0.00000025 | ||||
Swap Exact Token... | 14995167 | 2 hrs ago | IN | 0 frxETH | 0.00000025 | ||||
Swap Exact Token... | 14995158 | 2 hrs ago | IN | 0 frxETH | 0.00000016 | ||||
Swap Exact Token... | 14995137 | 2 hrs ago | IN | 0 frxETH | 0.00000018 | ||||
Swap Exact Token... | 14995136 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14995084 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14995067 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14994949 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14994910 | 2 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14993489 | 3 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14993434 | 3 hrs ago | IN | 0 frxETH | 0.00000043 | ||||
Swap Exact Token... | 14992667 | 3 hrs ago | IN | 0 frxETH | 0.00000043 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
14999608 | 41 secs ago | 0.00124458 frxETH | ||||
14999608 | 41 secs ago | 0.00124458 frxETH | ||||
14994217 | 3 hrs ago | 0.00952804 frxETH | ||||
14994217 | 3 hrs ago | 0.00952804 frxETH | ||||
14992812 | 3 hrs ago | 0.032 frxETH | ||||
14992812 | 3 hrs ago | 0.032 frxETH | ||||
14991433 | 4 hrs ago | 0.03004174 frxETH | ||||
14991433 | 4 hrs ago | 0.03004174 frxETH | ||||
14989881 | 5 hrs ago | 0.00170733 frxETH | ||||
14989881 | 5 hrs ago | 0.00170733 frxETH | ||||
14989671 | 5 hrs ago | 0.00138186 frxETH | ||||
14989671 | 5 hrs ago | 0.00138186 frxETH | ||||
14989467 | 5 hrs ago | 0.00108512 frxETH | ||||
14989467 | 5 hrs ago | 0.00108512 frxETH | ||||
14988308 | 6 hrs ago | 0.00073783 frxETH | ||||
14988308 | 6 hrs ago | 0.00073783 frxETH | ||||
14987930 | 6 hrs ago | 0.00024577 frxETH | ||||
14987930 | 6 hrs ago | 0.00024577 frxETH | ||||
14987019 | 7 hrs ago | 0.0004091 frxETH | ||||
14987019 | 7 hrs ago | 0.0004091 frxETH | ||||
14987006 | 7 hrs ago | 0.00036128 frxETH | ||||
14987006 | 7 hrs ago | 0.00036128 frxETH | ||||
14986997 | 7 hrs ago | 0.00034491 frxETH | ||||
14986997 | 7 hrs ago | 0.00034491 frxETH | ||||
14983731 | 8 hrs ago | 0.00009842 frxETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FraxswapRouter
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; // Sources flattened with hardhat v2.19.4 https://hardhat.org // File contracts/Fraxswap/core/interfaces/IUniswapV2PairV5.sol interface IUniswapV2PairV5 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } // File contracts/Fraxswap/core/interfaces/IFraxswapPair.sol // Original license: SPDX_License_Identifier: GPL-2.0-or-later // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ========================= IFraxswapPair ========================== // ==================================================================== // Fraxswap LP Pair Interface // Inspired by https://www.paradigm.xyz/2021/07/twamm // https://github.com/para-dave/twamm // Frax Finance: https://github.com/FraxFinance // Primary Author(s) // Rich Gee: https://github.com/zer0blockchain // Dennis: https://github.com/denett // Reviewer(s) / Contributor(s) // Travis Moore: https://github.com/FortisFortuna // Sam Kazemian: https://github.com/samkazemian interface IFraxswapPair is IUniswapV2PairV5 { // TWAMM event LongTermSwap0To1(address indexed addr, uint256 orderId, uint256 amount0In, uint256 numberOfTimeIntervals); event LongTermSwap1To0(address indexed addr, uint256 orderId, uint256 amount1In, uint256 numberOfTimeIntervals); event CancelLongTermOrder(address indexed addr, uint256 orderId, address sellToken, uint256 unsoldAmount, address buyToken, uint256 purchasedAmount); event WithdrawProceedsFromLongTermOrder(address indexed addr, uint256 orderId, address indexed proceedToken, uint256 proceeds, bool orderExpired); function fee() external view returns (uint); function longTermSwapFrom0To1(uint256 amount0In, uint256 numberOfTimeIntervals) external returns (uint256 orderId); function longTermSwapFrom1To0(uint256 amount1In, uint256 numberOfTimeIntervals) external returns (uint256 orderId); function cancelLongTermSwap(uint256 orderId) external; function withdrawProceedsFromLongTermSwap(uint256 orderId) external returns (bool is_expired, address rewardTkn, uint256 totalReward); function executeVirtualOrders(uint256 blockTimestamp) external; function getAmountOut(uint amountIn, address tokenIn) external view returns (uint); function getAmountIn(uint amountOut, address tokenOut) external view returns (uint); function orderTimeInterval() external returns (uint256); function getTWAPHistoryLength() external view returns (uint); function getTwammReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast, uint112 _twammReserve0, uint112 _twammReserve1, uint256 _fee); function getReserveAfterTwamm(uint256 blockTimestamp) external view returns (uint112 _reserve0, uint112 _reserve1, uint256 lastVirtualOrderTimestamp, uint112 _twammReserve0, uint112 _twammReserve1); function getNextOrderID() external view returns (uint256); function getOrderIDsForUser(address user) external view returns (uint256[] memory); function getOrderIDsForUserLength(address user) external view returns (uint256); // function getDetailedOrdersForUser(address user, uint256 offset, uint256 limit) external view returns (LongTermOrdersLib.Order[] memory detailed_orders); function twammUpToDate() external view returns (bool); function getTwammState() external view returns (uint256 token0Rate, uint256 token1Rate, uint256 lastVirtualOrderTimestamp, uint256 orderTimeInterval_rtn, uint256 rewardFactorPool0, uint256 rewardFactorPool1); function getTwammSalesRateEnding(uint256 _blockTimestamp) external view returns (uint256 orderPool0SalesRateEnding, uint256 orderPool1SalesRateEnding); function getTwammRewardFactor(uint256 _blockTimestamp) external view returns (uint256 rewardFactorPool0AtTimestamp, uint256 rewardFactorPool1AtTimestamp); function getTwammOrder(uint256 orderId) external view returns (uint256 id, uint256 creationTimestamp, uint256 expirationTimestamp, uint256 saleRate, address owner, address sellTokenAddr, address buyTokenAddr); function getTwammOrderProceedsView(uint256 orderId, uint256 blockTimestamp) external view returns (bool orderExpired, uint256 totalReward); function getTwammOrderProceeds(uint256 orderId) external returns (bool orderExpired, uint256 totalReward); function togglePauseNewSwaps() external; } // File contracts/Fraxswap/core/interfaces/IUniswapV2FactoryV5.sol interface IUniswapV2FactoryV5 { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function globalPause() external view returns (bool); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function createPair(address tokenA, address tokenB, uint fee) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; function toggleGlobalPause() external; } // File contracts/Fraxswap/libraries/TransferHelper.sol // Original license: SPDX_License_Identifier: GPL-3.0-or-later // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper::safeApprove: approve failed' ); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper::safeTransfer: transfer failed' ); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper::transferFrom: transferFrom failed' ); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); } } // File contracts/Fraxswap/periphery/interfaces/IERC20.sol interface IERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); } // File contracts/Fraxswap/periphery/interfaces/IUniswapV2Router01V5.sol interface IUniswapV2Router01V5 { function factory() external view returns (address); function WETH() external view returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } // File contracts/Fraxswap/periphery/interfaces/IUniswapV2Router02V5.sol interface IUniswapV2Router02V5 is IUniswapV2Router01V5 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } // File contracts/Fraxswap/periphery/interfaces/IWETH.sol interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; } // File contracts/Fraxswap/periphery/libraries/FraxswapRouterLibrary.sol // Original license: SPDX_License_Identifier: BUSL-1.1 // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ======================= FraxswapRouterLibrary ====================== // ==================================================================== // Fraxswap Router Library Functions // Inspired by https://www.paradigm.xyz/2021/07/twamm // https://github.com/para-dave/twamm // Frax Finance: https://github.com/FraxFinance // Primary Author(s) // Rich Gee: https://github.com/zer0blockchain // Dennis: https://github.com/denett // Logic / Algorithm Ideas // FrankieIsLost: https://github.com/FrankieIsLost // Reviewer(s) / Contributor(s) // Travis Moore: https://github.com/FortisFortuna // Sam Kazemian: https://github.com/samkazemian // Drake Evans: https://github.com/DrakeEvans // Jack Corddry: https://github.com/corddry // Justin Moore: https://github.com/0xJM library FraxswapRouterLibrary { bytes public constant INIT_CODE_HASH = hex'676b4c9b92980c4e7823b43031b17d7299896d1cd7d147104ad8e21692123fa1'; // init code / init hash // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, 'FraxswapRouterLibrary: IDENTICAL_ADDRESSES'); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), 'FraxswapRouterLibrary: ZERO_ADDRESS'); } // calculates the CREATE2 address for a pair without making any external calls function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = address(uint160(uint(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), INIT_CODE_HASH // init code / init hash ))))); } // fetches and sorts the reserves for a pair function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { (address token0,) = sortTokens(tokenA, tokenB); (uint reserve0, uint reserve1,) = IFraxswapPair(pairFor(factory, tokenA, tokenB)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } function getReservesWithTwamm(address factory, address tokenA, address tokenB) internal returns (uint reserveA, uint reserveB, uint twammReserveA, uint twammReserveB) { (address token0,) = sortTokens(tokenA, tokenB); IFraxswapPair pair = IFraxswapPair(pairFor(factory, tokenA, tokenB)); pair.executeVirtualOrders(block.timestamp); (uint reserve0, uint reserve1,,uint twammReserve0, uint twammReserve1, ) = pair.getTwammReserves(); (reserveA, reserveB, twammReserveA, twammReserveB) = tokenA == token0 ? (reserve0, reserve1, twammReserve0, twammReserve1) : (reserve1, reserve0, twammReserve1, twammReserve0); } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { require(amountA > 0, 'FraxswapRouterLibrary: INSUFFICIENT_AMOUNT'); require(reserveA > 0 && reserveB > 0, 'FraxswapRouterLibrary: INSUFFICIENT_LIQUIDITY'); amountB = amountA * reserveB / reserveA; } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'FraxswapRouterLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { IFraxswapPair pair = IFraxswapPair(FraxswapRouterLibrary.pairFor(factory, path[i], path[i + 1])); require(pair.twammUpToDate(), 'twamm out of date'); amounts[i + 1] = getAmountOutU112Fixed(address(pair), amounts[i], path[i]); } } // performs chained getAmountIn calculations on any number of pairs function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'FraxswapRouterLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { IFraxswapPair pair = IFraxswapPair(FraxswapRouterLibrary.pairFor(factory, path[i - 1], path[i])); require(pair.twammUpToDate(), 'twamm out of date'); amounts[i - 1] = getAmountInU112Fixed(address(pair), amounts[i], path[i - 1]); } } // performs chained getAmountOut calculations on any number of pairs with Twamm function getAmountsOutWithTwamm(address factory, uint amountIn, address[] memory path) internal returns (uint[] memory amounts) { require(path.length >= 2, 'FraxswapRouterLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { IFraxswapPair pair = IFraxswapPair(FraxswapRouterLibrary.pairFor(factory, path[i], path[i + 1])); pair.executeVirtualOrders(block.timestamp); amounts[i + 1] = getAmountOutU112Fixed(address(pair), amounts[i], path[i]); } } // performs chained getAmountIn calculations on any number of pairs with Twamm function getAmountsInWithTwamm(address factory, uint amountOut, address[] memory path) internal returns (uint[] memory amounts) { require(path.length >= 2, 'FraxswapRouterLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { IFraxswapPair pair = IFraxswapPair(FraxswapRouterLibrary.pairFor(factory, path[i - 1], path[i])); pair.executeVirtualOrders(block.timestamp); amounts[i - 1] = getAmountInU112Fixed(address(pair), amounts[i], path[i - 1]); } } // Fixes overflow issues with some tokens // ===================================================== // given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountInU112Fixed(address _pairAddress, uint _amountOut, address _tokenOut) internal view returns (uint) { IFraxswapPair pair = IFraxswapPair(_pairAddress); (uint112 _reserve0, uint112 _reserve1, ) = pair.getReserves(); (uint112 _reserveIn, uint112 _reserveOut) = _tokenOut == pair.token0() ? (_reserve1, _reserve0) : (_reserve0, _reserve1); require(_amountOut > 0 && _reserveIn > 0 && _reserveOut > 0); // INSUFFICIENT_OUTPUT_AMOUNT, INSUFFICIENT_LIQUIDITY uint numerator = uint256(_reserveIn) * _amountOut * 10000; uint denominator = (uint256(_reserveOut) - _amountOut) * pair.fee(); return (numerator / denominator) + 1; } // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOutU112Fixed(address _pairAddress, uint _amountIn, address _tokenIn) internal view returns (uint) { IFraxswapPair pair = IFraxswapPair(_pairAddress); (uint112 _reserve0, uint112 _reserve1, ) = pair.getReserves(); (uint112 _reserveIn, uint112 _reserveOut) = _tokenIn == pair.token0() ? (_reserve0, _reserve1) : (_reserve1, _reserve0); require(_amountIn > 0 && _reserveIn > 0 && _reserveOut > 0); // INSUFFICIENT_INPUT_AMOUNT, INSUFFICIENT_LIQUIDITY uint amountInWithFee = uint256(_amountIn) * pair.fee(); uint numerator = amountInWithFee * uint256(_reserveOut); uint denominator = (uint256(_reserveIn) * 10000) + amountInWithFee; return numerator / denominator; } } // File contracts/Fraxswap/periphery/FraxswapRouter.sol // Original license: SPDX_License_Identifier: BUSL-1.1 // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ========================== FraxswapRouter ========================== // ==================================================================== // TWAMM Router // Inspired by https://www.paradigm.xyz/2021/07/twamm // https://github.com/para-dave/twamm // 2.0.1: UInt112 fixes // Frax Finance: https://github.com/FraxFinance // Primary Author(s) // Rich Gee: https://github.com/zer0blockchain // Dennis: https://github.com/denett // Logic / Algorithm Ideas // FrankieIsLost: https://github.com/FrankieIsLost // Reviewer(s) / Contributor(s) // Travis Moore: https://github.com/FortisFortuna // Sam Kazemian: https://github.com/samkazemian // Drake Evans: https://github.com/DrakeEvans // Jack Corddry: https://github.com/corddry // Justin Moore: https://github.com/0xJM contract FraxswapRouter is IUniswapV2Router02V5 { address public immutable override factory; address public immutable override WETH; string constant public version = "2.0.1"; modifier ensure(uint deadline) { require(deadline >= block.timestamp, 'FraxswapV1Router: EXPIRED'); _; } constructor(address _factory, address _WETH) public { factory = _factory; WETH = _WETH; } receive() external payable { assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract } function INIT_CODE_HASH() public pure returns (bytes memory hash) { return FraxswapRouterLibrary.INIT_CODE_HASH; } // **** ADD LIQUIDITY **** function _addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin ) internal virtual returns (uint amountA, uint amountB) { // create the pair if it doesn't exist yet if (IUniswapV2FactoryV5(factory).getPair(tokenA, tokenB) == address(0)) { IUniswapV2FactoryV5(factory).createPair(tokenA, tokenB); } (uint reserveA, uint reserveB,,) = FraxswapRouterLibrary.getReservesWithTwamm(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint amountBOptimal = FraxswapRouterLibrary.quote(amountADesired, reserveA, reserveB); if (amountBOptimal <= amountBDesired) { require(amountBOptimal >= amountBMin, 'FraxswapV1Router: INSUFFICIENT_B_AMOUNT'); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint amountAOptimal = FraxswapRouterLibrary.quote(amountBDesired, reserveB, reserveA); assert(amountAOptimal <= amountADesired); require(amountAOptimal >= amountAMin, 'FraxswapV1Router: INSUFFICIENT_A_AMOUNT'); (amountA, amountB) = (amountAOptimal, amountBDesired); } } } function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) { (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin); address pair = FraxswapRouterLibrary.pairFor(factory, tokenA, tokenB); TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB); liquidity = IFraxswapPair(pair).mint(to); } function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) { (amountToken, amountETH) = _addLiquidity( token, WETH, amountTokenDesired, msg.value, amountTokenMin, amountETHMin ); address pair = FraxswapRouterLibrary.pairFor(factory, token, WETH); TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken); IWETH(WETH).deposit{value: amountETH}(); assert(IWETH(WETH).transfer(pair, amountETH)); liquidity = IFraxswapPair(pair).mint(to); // refund dust eth, if any if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); } // **** REMOVE LIQUIDITY **** function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) { address pair = FraxswapRouterLibrary.pairFor(factory, tokenA, tokenB); IFraxswapPair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair (uint amount0, uint amount1) = IFraxswapPair(pair).burn(to); (address token0,) = FraxswapRouterLibrary.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); require(amountA >= amountAMin, 'FraxswapV1Router: INSUFFICIENT_A_AMOUNT'); require(amountB >= amountBMin, 'FraxswapV1Router: INSUFFICIENT_B_AMOUNT'); } function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) { (amountToken, amountETH) = removeLiquidity( token, WETH, liquidity, amountTokenMin, amountETHMin, address(this), deadline ); TransferHelper.safeTransfer(token, to, amountToken); IWETH(WETH).withdraw(amountETH); TransferHelper.safeTransferETH(to, amountETH); } function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external virtual override returns (uint amountA, uint amountB) { address pair = FraxswapRouterLibrary.pairFor(factory, tokenA, tokenB); uint value = approveMax ? type(uint).max : liquidity; IFraxswapPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline); } function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external virtual override returns (uint amountToken, uint amountETH) { address pair = FraxswapRouterLibrary.pairFor(factory, token, WETH); uint value = approveMax ? type(uint).max : liquidity; IFraxswapPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline); } // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) **** function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) public virtual override ensure(deadline) returns (uint amountETH) { (, amountETH) = removeLiquidity( token, WETH, liquidity, amountTokenMin, amountETHMin, address(this), deadline ); TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this))); IWETH(WETH).withdraw(amountETH); TransferHelper.safeTransferETH(to, amountETH); } function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external virtual override returns (uint amountETH) { address pair = FraxswapRouterLibrary.pairFor(factory, token, WETH); uint value = approveMax ? type(uint).max : liquidity; IFraxswapPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); amountETH = removeLiquidityETHSupportingFeeOnTransferTokens( token, liquidity, amountTokenMin, amountETHMin, to, deadline ); } // **** SWAP **** // requires the initial amount to have already been sent to the first pair function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0,) = FraxswapRouterLibrary.sortTokens(input, output); uint amountOut = amounts[i + 1]; (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); address to = i < path.length - 2 ? FraxswapRouterLibrary.pairFor(factory, output, path[i + 2]) : _to; IFraxswapPair(FraxswapRouterLibrary.pairFor(factory, input, output)).swap( amount0Out, amount1Out, to, new bytes(0) ); } } function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external virtual override ensure(deadline) returns (uint[] memory amounts) { amounts = FraxswapRouterLibrary.getAmountsOutWithTwamm(factory, amountIn, path); require(amounts[amounts.length - 1] >= amountOutMin, 'FraxswapV1Router: INSUFFICIENT_OUTPUT_AMOUNT'); TransferHelper.safeTransferFrom( path[0], msg.sender, FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external virtual override ensure(deadline) returns (uint[] memory amounts) { amounts = FraxswapRouterLibrary.getAmountsInWithTwamm(factory, amountOut, path); require(amounts[0] <= amountInMax, 'FraxswapV1Router: EXCESSIVE_INPUT_AMOUNT'); TransferHelper.safeTransferFrom( path[0], msg.sender, FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external virtual override payable ensure(deadline) returns (uint[] memory amounts) { require(path[0] == WETH, 'FraxswapV1Router: INVALID_PATH'); amounts = FraxswapRouterLibrary.getAmountsOutWithTwamm(factory, msg.value, path); require(amounts[amounts.length - 1] >= amountOutMin, 'FraxswapV1Router: INSUFFICIENT_OUTPUT_AMOUNT'); IWETH(WETH).deposit{value: amounts[0]}(); assert(IWETH(WETH).transfer(FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amounts[0])); _swap(amounts, path, to); } function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external virtual override ensure(deadline) returns (uint[] memory amounts) { require(path[path.length - 1] == WETH, 'FraxswapV1Router: INVALID_PATH'); amounts = FraxswapRouterLibrary.getAmountsInWithTwamm(factory, amountOut, path); require(amounts[0] <= amountInMax, 'FraxswapV1Router: EXCESSIVE_INPUT_AMOUNT'); TransferHelper.safeTransferFrom( path[0], msg.sender, FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, address(this)); IWETH(WETH).withdraw(amounts[amounts.length - 1]); TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); } function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external virtual override ensure(deadline) returns (uint[] memory amounts) { require(path[path.length - 1] == WETH, 'FraxswapV1Router: INVALID_PATH'); amounts = FraxswapRouterLibrary.getAmountsOutWithTwamm(factory, amountIn, path); require(amounts[amounts.length - 1] >= amountOutMin, 'FraxswapV1Router: INSUFFICIENT_OUTPUT_AMOUNT'); TransferHelper.safeTransferFrom( path[0], msg.sender, FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, address(this)); IWETH(WETH).withdraw(amounts[amounts.length - 1]); TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); } function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external virtual override payable ensure(deadline) returns (uint[] memory amounts) { require(path[0] == WETH, 'FraxswapV1Router: INVALID_PATH'); amounts = FraxswapRouterLibrary.getAmountsInWithTwamm(factory, amountOut, path); require(amounts[0] <= msg.value, 'FraxswapV1Router: EXCESSIVE_INPUT_AMOUNT'); IWETH(WETH).deposit{value: amounts[0]}(); assert(IWETH(WETH).transfer(FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amounts[0])); _swap(amounts, path, to); // refund dust eth, if any if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); } // **** SWAP (supporting fee-on-transfer tokens) **** // requires the initial amount to have already been sent to the first pair function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0,) = FraxswapRouterLibrary.sortTokens(input, output); IFraxswapPair pair = IFraxswapPair(FraxswapRouterLibrary.pairFor(factory, input, output)); uint amountInput; uint amountOutput; { // scope to avoid stack too deep errors (uint reserveInput, uint reserveOutput, uint twammReserveInput, uint twammReserveOutput) = FraxswapRouterLibrary.getReservesWithTwamm(factory, input, output); amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput - twammReserveInput; amountOutput = FraxswapRouterLibrary.getAmountOutU112Fixed(address(pair), amountInput, input); } (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); address to = i < path.length - 2 ? FraxswapRouterLibrary.pairFor(factory, output, path[i + 2]) : _to; pair.swap(amount0Out, amount1Out, to, new bytes(0)); } } function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external virtual override ensure(deadline) { TransferHelper.safeTransferFrom( path[0], msg.sender, FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amountIn ); uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to); require( IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin, 'FraxswapV1Router: INSUFFICIENT_OUTPUT_AMOUNT' ); } function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external virtual override payable ensure(deadline) { require(path[0] == WETH, 'FraxswapV1Router: INVALID_PATH'); uint amountIn = msg.value; IWETH(WETH).deposit{value: amountIn}(); assert(IWETH(WETH).transfer(FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amountIn)); uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to); require( IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin, 'FraxswapV1Router: INSUFFICIENT_OUTPUT_AMOUNT' ); } function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external virtual override ensure(deadline) { require(path[path.length - 1] == WETH, 'FraxswapV1Router: INVALID_PATH'); TransferHelper.safeTransferFrom( path[0], msg.sender, FraxswapRouterLibrary.pairFor(factory, path[0], path[1]), amountIn ); _swapSupportingFeeOnTransferTokens(path, address(this)); uint amountOut = IERC20(WETH).balanceOf(address(this)); require(amountOut >= amountOutMin, 'FraxswapV1Router: INSUFFICIENT_OUTPUT_AMOUNT'); IWETH(WETH).withdraw(amountOut); TransferHelper.safeTransferETH(to, amountOut); } // **** LIBRARY FUNCTIONS **** function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) { return FraxswapRouterLibrary.quote(amountA, reserveA, reserveB); } function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure virtual override returns (uint amountOut) { revert("Deprecated: Use getAmountsOut"); // depends on the fee of the pool } function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure virtual override returns (uint amountIn) { revert("Deprecated: Use getAmountsIn"); // depends on the fee of the pool } function getAmountsOut(uint amountIn, address[] memory path) public view virtual override returns (uint[] memory amounts) { return FraxswapRouterLibrary.getAmountsOut(factory, amountIn, path); } function getAmountsIn(uint amountOut, address[] memory path) public view virtual override returns (uint[] memory amounts) { return FraxswapRouterLibrary.getAmountsIn(factory, amountOut, path); } function getAmountsOutWithTwamm(uint amountIn, address[] memory path) public returns (uint[] memory amounts) { return FraxswapRouterLibrary.getAmountsOutWithTwamm(factory, amountIn, path); } function getAmountsInWithTwamm(uint amountOut, address[] memory path) public returns (uint[] memory amounts) { return FraxswapRouterLibrary.getAmountsInWithTwamm(factory, amountOut, path); } }
{ "remappings": [ "ds-test/=lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "frax-std/=node_modules/frax-standard-solidity/src/", "src/=src/", "frax-ether-redemption-queue/=lib/frax-ether-redemption-queue-dev/src/", "solmate/=node_modules/solmate/", "@chainlink/=node_modules/@chainlink/", "@openzeppelin/=node_modules/@openzeppelin/", "@eth-optimism/=node_modules/@eth-optimism/", "frax-standard-solidity/=node_modules/frax-standard-solidity/", "solidity-bytes-utils/=node_modules/solidity-bytes-utils/" ], "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": false }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"INIT_CODE_HASH","outputs":[{"internalType":"bytes","name":"hash","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsInWithTwamm","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOutWithTwamm","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c06040523480156200001157600080fd5b506040516200615238038062006152833981016040819052620000349162000069565b6001600160a01b039182166080521660a052620000a1565b80516001600160a01b03811681146200006457600080fd5b919050565b600080604083850312156200007d57600080fd5b62000088836200004c565b915062000098602084016200004c565b90509250929050565b60805160a051615f0a62000248600039600081816101d80152818161049e015281816106c60152818161072e0152818161089e01528181610b880152818161103d0152818161123f01528181611778015281816118cb01528181611a0c01528181611af601528181611ce801528181611d8301528181612149015281816122400152818161235501528181612436015281816124b701528181612b0901528181612e1201528181612e6801528181612e9c01528181612f640152818161310d015281816132f3015261338e01526000818161058a0152818161097101528181610ab301528181610c7b01528181610cb401528181610e53015281816111100152818161121d015281816113fc015281816116d001528181611bd501528181611dc201528181611fbc015281816122c2015281816124f6015281816127cd01528181612ab701528181612ae701528181612cb801528181612e46015281816131ec015281816133cd01528181613dca01528181613dfd015281816144050152818161443b0152818161458f01528181614bf101528181614cc60152614d3d0152615f0a6000f3fe6080604052600436106101bb5760003560e01c806385f8c259116100ec578063baa2abde1161008a578063ded9382a11610064578063ded9382a146105cc578063e8e33700146105ec578063f305d71914610627578063fb3bdb411461063a57600080fd5b8063baa2abde14610558578063c45a015514610578578063d06ca61f146105ac57600080fd5b8063ad615dec116100c6578063ad615dec146104e5578063af2979eb14610505578063b66caf0614610525578063b6f9de951461054557600080fd5b806385f8c2591461044c5780638803dbee1461046c578063ad5c46481461048c57600080fd5b80634a25d94a116101595780635c11d795116101335780635c11d795146103d9578063704c32cf146103f9578063791ac947146104195780637ff36ab51461043957600080fd5b80634a25d94a1461035057806354fd4d50146103705780635b0d5984146103b957600080fd5b80631f00ca74116101955780631f00ca74146102a15780632195995c146102c1578063257671f5146102e157806338ed17391461033057600080fd5b806302751cec1461020c578063054d50d41461024657806318cbafe51461027457600080fd5b36610207573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102055761020561556c565b005b600080fd5b34801561021857600080fd5b5061022c6102273660046155d0565b61064d565b604080519283526020830191909152015b60405180910390f35b34801561025257600080fd5b5061026661026136600461562e565b6107b5565b60405190815260200161023d565b34801561028057600080fd5b5061029461028f36600461569f565b61081a565b60405161023d9190615712565b3480156102ad57600080fd5b506102946102bc366004615785565b610c74565b3480156102cd57600080fd5b5061022c6102dc366004615893565b610caa565b3480156102ed57600080fd5b506040805180820190915260208082527f676b4c9b92980c4e7823b43031b17d7299896d1cd7d147104ad8e21692123fa1908201525b60405161023d91906159ab565b34801561033c57600080fd5b5061029461034b36600461569f565b610de1565b34801561035c57600080fd5b5061029461036b36600461569f565b610fb9565b34801561037c57600080fd5b506103236040518060400160405280600581526020017f322e302e3100000000000000000000000000000000000000000000000000000081525081565b3480156103c557600080fd5b506102666103d43660046159be565b611215565b3480156103e557600080fd5b506102056103f436600461569f565b611360565b34801561040557600080fd5b50610294610414366004615785565b6116c9565b34801561042557600080fd5b5061020561043436600461569f565b6116f6565b610294610447366004615a54565b611a87565b34801561045857600080fd5b5061026661046736600461562e565b611ee5565b34801561047857600080fd5b5061029461048736600461569f565b611f4a565b34801561049857600080fd5b506104c07f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b3480156104f157600080fd5b5061026661050036600461562e565b6120c1565b34801561051157600080fd5b506102666105203660046155d0565b6120d6565b34801561053157600080fd5b50610294610540366004615785565b6122bb565b610205610553366004615a54565b6122e8565b34801561056457600080fd5b5061022c610573366004615abb565b612758565b34801561058457600080fd5b506104c07f000000000000000000000000000000000000000000000000000000000000000081565b3480156105b857600080fd5b506102946105c7366004615785565b612ab0565b3480156105d857600080fd5b5061022c6105e73660046159be565b612add565b3480156105f857600080fd5b5061060c610607366004615b2d565b612c2e565b6040805193845260208401929092529082015260600161023d565b61060c6106353660046155d0565b612d9c565b610294610648366004615a54565b61309e565b60008082428110156106c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064015b60405180910390fd5b6106ef897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a612758565b90935091506106ff898685613532565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561078757600080fd5b505af115801561079b573d6000803e3d6000fd5b505050506107a985836136c8565b50965096945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f446570726563617465643a2055736520676574416d6f756e74734f757400000060448201526000906064016106b7565b60608142811015610887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001686866108cb600182615bd8565b8181106108da576108da615beb565b90506020020160208101906108ef9190615c1a565b73ffffffffffffffffffffffffffffffffffffffff161461096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b6109ca7f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506137d792505050565b91508682600184516109dc9190615bd8565b815181106109ec576109ec615beb565b60200260200101511015610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b610b4786866000818110610a9857610a98615beb565b9050602002016020810190610aad9190615c1a565b33610b277f00000000000000000000000000000000000000000000000000000000000000008a8a6000818110610ae557610ae5615beb565b9050602002016020810190610afa9190615c1a565b8b8b6001818110610b0d57610b0d615beb565b9050602002016020810190610b229190615c1a565b613a2b565b85600081518110610b3a57610b3a615beb565b6020026020010151613b2e565b610b8682878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613ccd915050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d8360018551610bd19190615bd8565b81518110610be157610be1615beb565b60200260200101516040518263ffffffff1660e01b8152600401610c0791815260200190565b600060405180830381600087803b158015610c2157600080fd5b505af1158015610c35573d6000803e3d6000fd5b50505050610c69848360018551610c4c9190615bd8565b81518110610c5c57610c5c615beb565b60200260200101516136c8565b509695505050505050565b6060610ca17f00000000000000000000000000000000000000000000000000000000000000008484613ed8565b90505b92915050565b6000806000610cda7f00000000000000000000000000000000000000000000000000000000000000008f8f613a2b565b9050600087610ce9578c610d0b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015610da057600080fd5b505af1158015610db4573d6000803e3d6000fd5b50505050610dc78f8f8f8f8f8f8f612758565b809450819550505050509b509b9950505050505050505050565b60608142811015610e4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b610eac7f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506137d792505050565b9150868260018451610ebe9190615bd8565b81518110610ece57610ece615beb565b60200260200101511015610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b610f7a86866000818110610a9857610a98615beb565b610c6982878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613ccd915050565b60608142811015611026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016868661106a600182615bd8565b81811061107957611079615beb565b905060200201602081019061108e9190615c1a565b73ffffffffffffffffffffffffffffffffffffffff161461110b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b6111697f00000000000000000000000000000000000000000000000000000000000000008988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061418d92505050565b9150868260008151811061117f5761117f615beb565b60200260200101511115610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46726178737761705631526f757465723a204558434553534956455f494e505560448201527f545f414d4f554e5400000000000000000000000000000000000000000000000060648201526084016106b7565b6000806112637f00000000000000000000000000000000000000000000000000000000000000008d7f0000000000000000000000000000000000000000000000000000000000000000613a2b565b9050600086611272578b611294565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018a905260ff8816608482015260a4810187905260c4810186905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b15801561132957600080fd5b505af115801561133d573d6000803e3d6000fd5b5050505061134f8d8d8d8d8d8d6120d6565b9d9c50505050505050505050505050565b80428110156113cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b61145c858560008181106113e1576113e1615beb565b90506020020160208101906113f69190615c1a565b336114567f00000000000000000000000000000000000000000000000000000000000000008989600081811061142e5761142e615beb565b90506020020160208101906114439190615c1a565b8a8a6001818110610b0d57610b0d615beb565b8a613b2e565b6000858561146b600182615bd8565b81811061147a5761147a615beb565b905060200201602081019061148f9190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015291909116906370a0823190602401602060405180830381865afa1580156114fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115219190615c3e565b9050611561868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250614390915050565b86818787611570600182615bd8565b81811061157f5761157f615beb565b90506020020160208101906115949190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015291909116906370a08231906024015b602060405180830381865afa158015611603573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116279190615c3e565b6116319190615bd8565b10156116bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b5050505050505050565b6060610ca17f000000000000000000000000000000000000000000000000000000000000000084846137d7565b8042811015611761576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685856117a5600182615bd8565b8181106117b4576117b4615beb565b90506020020160208101906117c99190615c1a565b73ffffffffffffffffffffffffffffffffffffffff1614611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b61185c858560008181106113e1576113e1615beb565b61189a858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250614390915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194b9190615c3e565b9050868110156119dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015611a6557600080fd5b505af1158015611a79573d6000803e3d6000fd5b505050506116bf84826136c8565b60608142811015611af4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1686866000818110611b3e57611b3e615beb565b9050602002016020810190611b539190615c1a565b73ffffffffffffffffffffffffffffffffffffffff1614611bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b611c2e7f0000000000000000000000000000000000000000000000000000000000000000348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506137d792505050565b9150868260018451611c409190615bd8565b81518110611c5057611c50615beb565b60200260200101511015611ce6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db083600081518110611d3557611d35615beb565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d6857600080fd5b505af1158015611d7c573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb611df47f00000000000000000000000000000000000000000000000000000000000000008989600081811061142e5761142e615beb565b84600081518110611e0757611e07615beb565b60200260200101516040518363ffffffff1660e01b8152600401611e4d92919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015611e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e909190615c57565b611e9c57611e9c61556c565b611edb82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613ccd915050565b5095945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f446570726563617465643a2055736520676574416d6f756e7473496e0000000060448201526000906064016106b7565b60608142811015611fb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b6120157f00000000000000000000000000000000000000000000000000000000000000008988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061418d92505050565b9150868260008151811061202b5761202b615beb565b60200260200101511115610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46726178737761705631526f757465723a204558434553534956455f494e505560448201527f545f414d4f554e5400000000000000000000000000000000000000000000000060648201526084016106b7565b60006120ce84848461466a565b949350505050565b60008142811015612143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b612172887f00000000000000000000000000000000000000000000000000000000000000008989893089612758565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290935061221191508990869073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190615c3e565b613532565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561229957600080fd5b505af11580156122ad573d6000803e3d6000fd5b50505050610c6984836136c8565b6060610ca17f0000000000000000000000000000000000000000000000000000000000000000848461418d565b8042811015612353576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168585600081811061239d5761239d615beb565b90506020020160208101906123b29190615c1a565b73ffffffffffffffffffffffffffffffffffffffff161461242f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b60003490507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561249c57600080fd5b505af11580156124b0573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6125287f00000000000000000000000000000000000000000000000000000000000000008989600081811061142e5761142e615beb565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561259a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125be9190615c57565b6125ca576125ca61556c565b600086866125d9600182615bd8565b8181106125e8576125e8615beb565b90506020020160208101906125fd9190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291909116906370a0823190602401602060405180830381865afa15801561266b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268f9190615c3e565b90506126cf878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250614390915050565b878188886126de600182615bd8565b8181106126ed576126ed615beb565b90506020020160208101906127029190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015291909116906370a08231906024016115e6565b60008082428110156127c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b60006127f37f00000000000000000000000000000000000000000000000000000000000000008c8c613a2b565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af115801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190615c57565b506040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015612906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292a9190615c74565b91509150600061293a8e8e6147ac565b5090508073ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff161461297757818361297a565b82825b90975095508a871015612a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4160448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b89861015612a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4260448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b505050505097509795505050505050565b6060610ca17f00000000000000000000000000000000000000000000000000000000000000008484614956565b6000806000612b2d7f00000000000000000000000000000000000000000000000000000000000000008e7f0000000000000000000000000000000000000000000000000000000000000000613a2b565b9050600087612b3c578c612b5e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015612bf357600080fd5b505af1158015612c07573d6000803e3d6000fd5b50505050612c198e8e8e8e8e8e61064d565b909f909e509c50505050505050505050505050565b60008060008342811015612c9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b612cac8c8c8c8c8c8c614b9d565b90945092506000612cde7f00000000000000000000000000000000000000000000000000000000000000008e8e613a2b565b9050612cec8d338388613b2e565b612cf88c338387613b2e565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af1158015612d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8a9190615c3e565b92505050985098509895505050505050565b60008060008342811015612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b612e3a8a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c614b9d565b90945092506000612e8c7f00000000000000000000000000000000000000000000000000000000000000008c7f0000000000000000000000000000000000000000000000000000000000000000613a2b565b9050612e9a8b338388613b2e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612f0257600080fd5b505af1158015612f16573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015612fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd59190615c57565b612fe157612fe161556c565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af115801561304f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130739190615c3e565b925083341115613090576130903361308b8634615bd8565b6136c8565b505096509650969350505050565b6060814281101561310b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168686600081811061315557613155615beb565b905060200201602081019061316a9190615c1a565b73ffffffffffffffffffffffffffffffffffffffff16146131e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b6132457f00000000000000000000000000000000000000000000000000000000000000008888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061418d92505050565b9150348260008151811061325b5761325b615beb565b602002602001015111156132f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46726178737761705631526f757465723a204558434553534956455f494e505560448201527f545f414d4f554e5400000000000000000000000000000000000000000000000060648201526084016106b7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db08360008151811061334057613340615beb565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561337357600080fd5b505af1158015613387573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6133ff7f00000000000000000000000000000000000000000000000000000000000000008989600081811061142e5761142e615beb565b8460008151811061341257613412615beb565b60200260200101516040518363ffffffff1660e01b815260040161345892919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015613477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349b9190615c57565b6134a7576134a761556c565b6134e682878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613ccd915050565b816000815181106134f9576134f9615beb565b6020026020010151341115611edb57611edb338360008151811061351f5761351f615beb565b60200260200101513461308b9190615bd8565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916135c99190615c98565b6000604051808303816000865af19150503d8060008114613606576040519150601f19603f3d011682016040523d82523d6000602084013e61360b565b606091505b50915091508180156136355750805115806136355750808060200190518101906136359190615c57565b6136c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016106b7565b5050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516136ff9190615c98565b60006040518083038185875af1925050503d806000811461373c576040519150601f19603f3d011682016040523d82523d6000602084013e613741565b606091505b50509050806137d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c656400000000000000000000000060648201526084016106b7565b505050565b606060028251101561386b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff81111561388557613885615756565b6040519080825280602002602001820160405280156138ae578160200160208202803683370190505b50905082816000815181106138c5576138c5615beb565b60200260200101818152505060005b600183516138e29190615bd8565b811015613a235760006139348685848151811061390157613901615beb565b6020026020010151868560016139179190615cb4565b8151811061392757613927615beb565b6020026020010151613a2b565b6040517f2e0ae37500000000000000000000000000000000000000000000000000000000815242600482015290915073ffffffffffffffffffffffffffffffffffffffff821690632e0ae37590602401600060405180830381600087803b15801561399e57600080fd5b505af11580156139b2573d6000803e3d6000fd5b505050506139f3818484815181106139cc576139cc615beb565b60200260200101518685815181106139e6576139e6615beb565b6020026020010151614efc565b836139ff846001615cb4565b81518110613a0f57613a0f615beb565b6020908102919091010152506001016138d4565b509392505050565b6000806000613a3a85856147ac565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015291935091508690604801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012083830183528184527f676b4c9b92980c4e7823b43031b17d7299896d1cd7d147104ad8e21692123fa1848301529151613aee94939101615cc7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209695505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691613bcd9190615c98565b6000604051808303816000865af19150503d8060008114613c0a576040519150601f19603f3d011682016040523d82523d6000602084013e613c0f565b606091505b5091509150818015613c39575080511580613c39575080806020019051810190613c399190615c57565b613cc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c656400000000000000000000000000000060648201526084016106b7565b505050505050565b60005b60018351613cde9190615bd8565b811015613ed257600080848381518110613cfa57613cfa615beb565b602002602001015185846001613d109190615cb4565b81518110613d2057613d20615beb565b6020026020010151915091506000613d3883836147ac565b509050600087613d49866001615cb4565b81518110613d5957613d59615beb565b602002602001015190506000808373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614613da157826000613da5565b6000835b91509150600060028a51613db99190615bd8565b8810613dc55788613df6565b613df67f0000000000000000000000000000000000000000000000000000000000000000878c6139178c6002615cb4565b9050613e237f00000000000000000000000000000000000000000000000000000000000000008888613a2b565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613e6d576020820181803683370190505b506040518563ffffffff1660e01b8152600401613e8d9493929190615d3f565b600060405180830381600087803b158015613ea757600080fd5b505af1158015613ebb573d6000803e3d6000fd5b505060019099019850613cd0975050505050505050565b50505050565b6060600282511015613f6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff811115613f8657613f86615756565b604051908082528060200260200182016040528015613faf578160200160208202803683370190505b509050828160018351613fc29190615bd8565b81518110613fd257613fd2615beb565b602002602001018181525050600060018351613fee9190615bd8565b90505b8015613a235760006140338685614009600186615bd8565b8151811061401957614019615beb565b602002602001015186858151811061392757613927615beb565b90508073ffffffffffffffffffffffffffffffffffffffff1663a1462c196040518163ffffffff1660e01b8152600401602060405180830381865afa158015614080573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140a49190615c57565b61410a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f7477616d6d206f7574206f66206461746500000000000000000000000000000060448201526064016106b7565b6141538184848151811061412057614120615beb565b6020026020010151866001866141369190615bd8565b8151811061414657614146615beb565b6020026020010151615150565b8361415f600185615bd8565b8151811061416f5761416f615beb565b6020908102919091010152508061418581615d84565b915050613ff1565b6060600282511015614221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff81111561423b5761423b615756565b604051908082528060200260200182016040528015614264578160200160208202803683370190505b5090508281600183516142779190615bd8565b8151811061428757614287615beb565b6020026020010181815250506000600183516142a39190615bd8565b90505b8015613a235760006142be8685614009600186615bd8565b6040517f2e0ae37500000000000000000000000000000000000000000000000000000000815242600482015290915073ffffffffffffffffffffffffffffffffffffffff821690632e0ae37590602401600060405180830381600087803b15801561432857600080fd5b505af115801561433c573d6000803e3d6000fd5b505050506143568184848151811061412057614120615beb565b83614362600185615bd8565b8151811061437257614372615beb565b6020908102919091010152508061438881615d84565b9150506142a6565b60005b600183516143a19190615bd8565b8110156137d2576000808483815181106143bd576143bd615beb565b6020026020010151858460016143d39190615cb4565b815181106143e3576143e3615beb565b60200260200101519150915060006143fb83836147ac565b509050600061442b7f00000000000000000000000000000000000000000000000000000000000000008585613a2b565b90506000806000806000806144617f00000000000000000000000000000000000000000000000000000000000000008b8b6153a9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152949850929650909450925083918691908d16906370a0823190602401602060405180830381865afa1580156144dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145019190615c3e565b61450b9190615bd8565b6145159190615bd8565b955061452287878c614efc565b9450505050506000808573ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146145665782600061456a565b6000835b91509150600060028c5161457e9190615bd8565b8a1061458a578a6145bb565b6145bb7f0000000000000000000000000000000000000000000000000000000000000000898e6139178e6002615cb4565b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff87169063022c0d9f906146239086908690869060248101615d3f565b600060405180830381600087803b15801561463d57600080fd5b505af1158015614651573d6000803e3d6000fd5b50506001909b019a506143939950505050505050505050565b60008084116146fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4672617873776170526f757465724c6962726172793a20494e5355464649434960448201527f454e545f414d4f554e540000000000000000000000000000000000000000000060648201526084016106b7565b60008311801561470b5750600082115b614797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4672617873776170526f757465724c6962726172793a20494e5355464649434960448201527f454e545f4c49515549444954590000000000000000000000000000000000000060648201526084016106b7565b826147a28386615db9565b6120ce9190615dd0565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361486a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4672617873776170526f757465724c6962726172793a204944454e544943414c60448201527f5f4144445245535345530000000000000000000000000000000000000000000060648201526084016106b7565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16106148a45782846148a7565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff821661494f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a205a45524f5f4144445260448201527f455353000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b9250929050565b60606002825110156149ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff811115614a0457614a04615756565b604051908082528060200260200182016040528015614a2d578160200160208202803683370190505b5090508281600081518110614a4457614a44615beb565b60200260200101818152505060005b60018351614a619190615bd8565b811015613a23576000614a808685848151811061390157613901615beb565b90508073ffffffffffffffffffffffffffffffffffffffff1663a1462c196040518163ffffffff1660e01b8152600401602060405180830381865afa158015614acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614af19190615c57565b614b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f7477616d6d206f7574206f66206461746500000000000000000000000000000060448201526064016106b7565b614b6d818484815181106139cc576139cc615beb565b83614b79846001615cb4565b81518110614b8957614b89615beb565b602090810291909101015250600101614a53565b6040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152600091829182917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015614c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c5e9190615e0b565b73ffffffffffffffffffffffffffffffffffffffff1603614d35576040517fc9c6539600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015288811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303816000875af1158015614d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d339190615e0b565b505b600080614d637f00000000000000000000000000000000000000000000000000000000000000008b8b6153a9565b505091509150816000148015614d77575080155b15614d8757879350869250614eef565b6000614d9489848461466a565b9050878111614e385785811015614e2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4260448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b889450925082614eed565b6000614e4589848661466a565b905089811115614e5757614e5761556c565b87811015614ee7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4160448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b94508793505b505b5050965096945050505050565b6000808490506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015614f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f749190615e5a565b50915091506000808473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015614fc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614feb9190615e0b565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614615024578284615027565b83835b9150915060008811801561504b57506000826dffffffffffffffffffffffffffff16115b801561506757506000816dffffffffffffffffffffffffffff16115b61507057600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff1663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156150bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906150e19190615c3e565b6150eb908a615db9565b905060006151096dffffffffffffffffffffffffffff841683615db9565b905060008261512a6dffffffffffffffffffffffffffff8716612710615db9565b6151349190615cb4565b90506151408183615dd0565b9c9b505050505050505050505050565b6000808490506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156151a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906151c89190615e5a565b50915091506000808473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561521b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061523f9190615e0b565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161461527857838361527b565b82845b9150915060008811801561529f57506000826dffffffffffffffffffffffffffff16115b80156152bb57506000816dffffffffffffffffffffffffffff16115b6152c457600080fd5b60006152e0896dffffffffffffffffffffffffffff8516615db9565b6152ec90612710615db9565b905060008673ffffffffffffffffffffffffffffffffffffffff1663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa15801561533b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061535f9190615c3e565b6153798b6dffffffffffffffffffffffffffff8616615bd8565b6153839190615db9565b905061538f8183615dd0565b61539a906001615cb4565b9b9a5050505050505050505050565b60008060008060006153bb87876147ac565b50905060006153cb898989613a2b565b6040517f2e0ae37500000000000000000000000000000000000000000000000000000000815242600482015290915073ffffffffffffffffffffffffffffffffffffffff821690632e0ae37590602401600060405180830381600087803b15801561543557600080fd5b505af1158015615449573d6000803e3d6000fd5b505050506000806000808473ffffffffffffffffffffffffffffffffffffffff1663094cf1496040518163ffffffff1660e01b815260040160c060405180830381865afa15801561549e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906154c29190615e9d565b506dffffffffffffffffffffffffffff1694506dffffffffffffffffffffffffffff169450506dffffffffffffffffffffffffffff1693506dffffffffffffffffffffffffffff1693508573ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff1614615548578284828461554d565b838383835b809a50819b50829c50839d505050505050505050505093509350935093565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146155bd57600080fd5b50565b80356155cb8161559b565b919050565b60008060008060008060c087890312156155e957600080fd5b86356155f48161559b565b955060208701359450604087013593506060870135925060808701356156198161559b565b8092505060a087013590509295509295509295565b60008060006060848603121561564357600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261566c57600080fd5b50813567ffffffffffffffff81111561568457600080fd5b6020830191508360208260051b850101111561494f57600080fd5b60008060008060008060a087890312156156b857600080fd5b8635955060208701359450604087013567ffffffffffffffff8111156156dd57600080fd5b6156e989828a0161565a565b90955093505060608701356156fd8161559b565b80925050608087013590509295509295509295565b6020808252825182820181905260009190848201906040850190845b8181101561574a5783518352928401929184019160010161572e565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561579857600080fd5b8235915060208084013567ffffffffffffffff808211156157b857600080fd5b818601915086601f8301126157cc57600080fd5b8135818111156157de576157de615756565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561582157615821615756565b60405291825284820192508381018501918983111561583f57600080fd5b938501935b8285101561586457615855856155c0565b84529385019392850192615844565b8096505050505050509250929050565b80151581146155bd57600080fd5b803560ff811681146155cb57600080fd5b60008060008060008060008060008060006101608c8e0312156158b557600080fd5b8b356158c08161559b565b9a5060208c01356158d08161559b565b995060408c0135985060608c0135975060808c0135965060a08c01356158f58161559b565b955060c08c0135945060e08c013561590c81615874565b935061591b6101008d01615882565b92506101208c013591506101408c013590509295989b509295989b9093969950565b60005b83811015615958578181015183820152602001615940565b50506000910152565b6000815180845261597981602086016020860161593d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ca16020830184615961565b6000806000806000806000806000806101408b8d0312156159de57600080fd5b8a356159e98161559b565b995060208b0135985060408b0135975060608b0135965060808b0135615a0e8161559b565b955060a08b0135945060c08b0135615a2581615874565b9350615a3360e08c01615882565b92506101008b013591506101208b013590509295989b9194979a5092959850565b600080600080600060808688031215615a6c57600080fd5b85359450602086013567ffffffffffffffff811115615a8a57600080fd5b615a968882890161565a565b9095509350506040860135615aaa8161559b565b949793965091946060013592915050565b600080600080600080600060e0888a031215615ad657600080fd5b8735615ae18161559b565b96506020880135615af18161559b565b955060408801359450606088013593506080880135925060a0880135615b168161559b565b8092505060c0880135905092959891949750929550565b600080600080600080600080610100898b031215615b4a57600080fd5b8835615b558161559b565b97506020890135615b658161559b565b965060408901359550606089013594506080890135935060a0890135925060c0890135615b918161559b565b8092505060e089013590509295985092959890939650565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ca457610ca4615ba9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215615c2c57600080fd5b8135615c378161559b565b9392505050565b600060208284031215615c5057600080fd5b5051919050565b600060208284031215615c6957600080fd5b8151615c3781615874565b60008060408385031215615c8757600080fd5b505080516020909101519092909150565b60008251615caa81846020870161593d565b9190910192915050565b80820180821115610ca457610ca4615ba9565b7fff0000000000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008460601b16600182015282601582015260008251615d3081603585016020870161593d565b91909101603501949350505050565b84815283602082015273ffffffffffffffffffffffffffffffffffffffff83166040820152608060608201526000615d7a6080830184615961565b9695505050505050565b600081615d9357615d93615ba9565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610ca457610ca4615ba9565b600082615e06577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215615e1d57600080fd5b8151615c378161559b565b80516dffffffffffffffffffffffffffff811681146155cb57600080fd5b805163ffffffff811681146155cb57600080fd5b600080600060608486031215615e6f57600080fd5b615e7884615e28565b9250615e8660208501615e28565b9150615e9460408501615e46565b90509250925092565b60008060008060008060c08789031215615eb657600080fd5b615ebf87615e28565b9550615ecd60208801615e28565b9450615edb60408801615e46565b9350615ee960608801615e28565b9250615ef760808801615e28565b915060a08701519050929550929550929556000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6000000000000000000000000fc00000000000000000000000000000000000006
Deployed Bytecode
0x6080604052600436106101bb5760003560e01c806385f8c259116100ec578063baa2abde1161008a578063ded9382a11610064578063ded9382a146105cc578063e8e33700146105ec578063f305d71914610627578063fb3bdb411461063a57600080fd5b8063baa2abde14610558578063c45a015514610578578063d06ca61f146105ac57600080fd5b8063ad615dec116100c6578063ad615dec146104e5578063af2979eb14610505578063b66caf0614610525578063b6f9de951461054557600080fd5b806385f8c2591461044c5780638803dbee1461046c578063ad5c46481461048c57600080fd5b80634a25d94a116101595780635c11d795116101335780635c11d795146103d9578063704c32cf146103f9578063791ac947146104195780637ff36ab51461043957600080fd5b80634a25d94a1461035057806354fd4d50146103705780635b0d5984146103b957600080fd5b80631f00ca74116101955780631f00ca74146102a15780632195995c146102c1578063257671f5146102e157806338ed17391461033057600080fd5b806302751cec1461020c578063054d50d41461024657806318cbafe51461027457600080fd5b36610207573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000fc0000000000000000000000000000000000000616146102055761020561556c565b005b600080fd5b34801561021857600080fd5b5061022c6102273660046155d0565b61064d565b604080519283526020830191909152015b60405180910390f35b34801561025257600080fd5b5061026661026136600461562e565b6107b5565b60405190815260200161023d565b34801561028057600080fd5b5061029461028f36600461569f565b61081a565b60405161023d9190615712565b3480156102ad57600080fd5b506102946102bc366004615785565b610c74565b3480156102cd57600080fd5b5061022c6102dc366004615893565b610caa565b3480156102ed57600080fd5b506040805180820190915260208082527f676b4c9b92980c4e7823b43031b17d7299896d1cd7d147104ad8e21692123fa1908201525b60405161023d91906159ab565b34801561033c57600080fd5b5061029461034b36600461569f565b610de1565b34801561035c57600080fd5b5061029461036b36600461569f565b610fb9565b34801561037c57600080fd5b506103236040518060400160405280600581526020017f322e302e3100000000000000000000000000000000000000000000000000000081525081565b3480156103c557600080fd5b506102666103d43660046159be565b611215565b3480156103e557600080fd5b506102056103f436600461569f565b611360565b34801561040557600080fd5b50610294610414366004615785565b6116c9565b34801561042557600080fd5b5061020561043436600461569f565b6116f6565b610294610447366004615a54565b611a87565b34801561045857600080fd5b5061026661046736600461562e565b611ee5565b34801561047857600080fd5b5061029461048736600461569f565b611f4a565b34801561049857600080fd5b506104c07f000000000000000000000000fc0000000000000000000000000000000000000681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b3480156104f157600080fd5b5061026661050036600461562e565b6120c1565b34801561051157600080fd5b506102666105203660046155d0565b6120d6565b34801561053157600080fd5b50610294610540366004615785565b6122bb565b610205610553366004615a54565b6122e8565b34801561056457600080fd5b5061022c610573366004615abb565b612758565b34801561058457600080fd5b506104c07f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e681565b3480156105b857600080fd5b506102946105c7366004615785565b612ab0565b3480156105d857600080fd5b5061022c6105e73660046159be565b612add565b3480156105f857600080fd5b5061060c610607366004615b2d565b612c2e565b6040805193845260208401929092529082015260600161023d565b61060c6106353660046155d0565b612d9c565b610294610648366004615a54565b61309e565b60008082428110156106c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064015b60405180910390fd5b6106ef897f000000000000000000000000fc000000000000000000000000000000000000068a8a8a308a612758565b90935091506106ff898685613532565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561078757600080fd5b505af115801561079b573d6000803e3d6000fd5b505050506107a985836136c8565b50965096945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f446570726563617465643a2055736520676574416d6f756e74734f757400000060448201526000906064016106b7565b60608142811015610887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000fc000000000000000000000000000000000000061686866108cb600182615bd8565b8181106108da576108da615beb565b90506020020160208101906108ef9190615c1a565b73ffffffffffffffffffffffffffffffffffffffff161461096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b6109ca7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506137d792505050565b91508682600184516109dc9190615bd8565b815181106109ec576109ec615beb565b60200260200101511015610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b610b4786866000818110610a9857610a98615beb565b9050602002016020810190610aad9190615c1a565b33610b277f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68a8a6000818110610ae557610ae5615beb565b9050602002016020810190610afa9190615c1a565b8b8b6001818110610b0d57610b0d615beb565b9050602002016020810190610b229190615c1a565b613a2b565b85600081518110610b3a57610b3a615beb565b6020026020010151613b2e565b610b8682878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613ccd915050565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d8360018551610bd19190615bd8565b81518110610be157610be1615beb565b60200260200101516040518263ffffffff1660e01b8152600401610c0791815260200190565b600060405180830381600087803b158015610c2157600080fd5b505af1158015610c35573d6000803e3d6000fd5b50505050610c69848360018551610c4c9190615bd8565b81518110610c5c57610c5c615beb565b60200260200101516136c8565b509695505050505050565b6060610ca17f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68484613ed8565b90505b92915050565b6000806000610cda7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68f8f613a2b565b9050600087610ce9578c610d0b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015610da057600080fd5b505af1158015610db4573d6000803e3d6000fd5b50505050610dc78f8f8f8f8f8f8f612758565b809450819550505050509b509b9950505050505050505050565b60608142811015610e4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b610eac7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506137d792505050565b9150868260018451610ebe9190615bd8565b81518110610ece57610ece615beb565b60200260200101511015610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b610f7a86866000818110610a9857610a98615beb565b610c6982878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613ccd915050565b60608142811015611026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000fc0000000000000000000000000000000000000616868661106a600182615bd8565b81811061107957611079615beb565b905060200201602081019061108e9190615c1a565b73ffffffffffffffffffffffffffffffffffffffff161461110b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b6111697f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061418d92505050565b9150868260008151811061117f5761117f615beb565b60200260200101511115610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46726178737761705631526f757465723a204558434553534956455f494e505560448201527f545f414d4f554e5400000000000000000000000000000000000000000000000060648201526084016106b7565b6000806112637f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68d7f000000000000000000000000fc00000000000000000000000000000000000006613a2b565b9050600086611272578b611294565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018a905260ff8816608482015260a4810187905260c4810186905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b15801561132957600080fd5b505af115801561133d573d6000803e3d6000fd5b5050505061134f8d8d8d8d8d8d6120d6565b9d9c50505050505050505050505050565b80428110156113cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b61145c858560008181106113e1576113e1615beb565b90506020020160208101906113f69190615c1a565b336114567f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68989600081811061142e5761142e615beb565b90506020020160208101906114439190615c1a565b8a8a6001818110610b0d57610b0d615beb565b8a613b2e565b6000858561146b600182615bd8565b81811061147a5761147a615beb565b905060200201602081019061148f9190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015291909116906370a0823190602401602060405180830381865afa1580156114fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115219190615c3e565b9050611561868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250614390915050565b86818787611570600182615bd8565b81811061157f5761157f615beb565b90506020020160208101906115949190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015291909116906370a08231906024015b602060405180830381865afa158015611603573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116279190615c3e565b6116319190615bd8565b10156116bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b5050505050505050565b6060610ca17f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e684846137d7565b8042811015611761576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000fc000000000000000000000000000000000000061685856117a5600182615bd8565b8181106117b4576117b4615beb565b90506020020160208101906117c99190615c1a565b73ffffffffffffffffffffffffffffffffffffffff1614611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b61185c858560008181106113e1576113e1615beb565b61189a858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250614390915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194b9190615c3e565b9050868110156119dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015611a6557600080fd5b505af1158015611a79573d6000803e3d6000fd5b505050506116bf84826136c8565b60608142811015611af4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1686866000818110611b3e57611b3e615beb565b9050602002016020810190611b539190615c1a565b73ffffffffffffffffffffffffffffffffffffffff1614611bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b611c2e7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506137d792505050565b9150868260018451611c409190615bd8565b81518110611c5057611c50615beb565b60200260200101511015611ce6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4f60448201527f55545055545f414d4f554e54000000000000000000000000000000000000000060648201526084016106b7565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db083600081518110611d3557611d35615beb565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d6857600080fd5b505af1158015611d7c573d6000803e3d6000fd5b50505050507f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb611df47f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68989600081811061142e5761142e615beb565b84600081518110611e0757611e07615beb565b60200260200101516040518363ffffffff1660e01b8152600401611e4d92919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015611e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e909190615c57565b611e9c57611e9c61556c565b611edb82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613ccd915050565b5095945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f446570726563617465643a2055736520676574416d6f756e7473496e0000000060448201526000906064016106b7565b60608142811015611fb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b6120157f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061418d92505050565b9150868260008151811061202b5761202b615beb565b60200260200101511115610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46726178737761705631526f757465723a204558434553534956455f494e505560448201527f545f414d4f554e5400000000000000000000000000000000000000000000000060648201526084016106b7565b60006120ce84848461466a565b949350505050565b60008142811015612143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b612172887f000000000000000000000000fc000000000000000000000000000000000000068989893089612758565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290935061221191508990869073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190615c3e565b613532565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561229957600080fd5b505af11580156122ad573d6000803e3d6000fd5b50505050610c6984836136c8565b6060610ca17f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6848461418d565b8042811015612353576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff168585600081811061239d5761239d615beb565b90506020020160208101906123b29190615c1a565b73ffffffffffffffffffffffffffffffffffffffff161461242f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b60003490507f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561249c57600080fd5b505af11580156124b0573d6000803e3d6000fd5b50505050507f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6125287f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68989600081811061142e5761142e615beb565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561259a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125be9190615c57565b6125ca576125ca61556c565b600086866125d9600182615bd8565b8181106125e8576125e8615beb565b90506020020160208101906125fd9190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291909116906370a0823190602401602060405180830381865afa15801561266b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268f9190615c3e565b90506126cf878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250614390915050565b878188886126de600182615bd8565b8181106126ed576126ed615beb565b90506020020160208101906127029190615c1a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015291909116906370a08231906024016115e6565b60008082428110156127c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b60006127f37f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68c8c613a2b565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af115801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190615c57565b506040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015612906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292a9190615c74565b91509150600061293a8e8e6147ac565b5090508073ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff161461297757818361297a565b82825b90975095508a871015612a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4160448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b89861015612a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4260448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b505050505097509795505050505050565b6060610ca17f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68484614956565b6000806000612b2d7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68e7f000000000000000000000000fc00000000000000000000000000000000000006613a2b565b9050600087612b3c578c612b5e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015612bf357600080fd5b505af1158015612c07573d6000803e3d6000fd5b50505050612c198e8e8e8e8e8e61064d565b909f909e509c50505050505050505050505050565b60008060008342811015612c9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b612cac8c8c8c8c8c8c614b9d565b90945092506000612cde7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68e8e613a2b565b9050612cec8d338388613b2e565b612cf88c338387613b2e565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af1158015612d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8a9190615c3e565b92505050985098509895505050505050565b60008060008342811015612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b612e3a8a7f000000000000000000000000fc000000000000000000000000000000000000068b348c8c614b9d565b90945092506000612e8c7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68c7f000000000000000000000000fc00000000000000000000000000000000000006613a2b565b9050612e9a8b338388613b2e565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612f0257600080fd5b505af1158015612f16573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018990527f000000000000000000000000fc0000000000000000000000000000000000000616935063a9059cbb925060440190506020604051808303816000875af1158015612fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd59190615c57565b612fe157612fe161556c565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af115801561304f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130739190615c3e565b925083341115613090576130903361308b8634615bd8565b6136c8565b505096509650969350505050565b6060814281101561310b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f46726178737761705631526f757465723a20455850495245440000000000000060448201526064016106b7565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff168686600081811061315557613155615beb565b905060200201602081019061316a9190615c1a565b73ffffffffffffffffffffffffffffffffffffffff16146131e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46726178737761705631526f757465723a20494e56414c49445f50415448000060448201526064016106b7565b6132457f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061418d92505050565b9150348260008151811061325b5761325b615beb565b602002602001015111156132f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f46726178737761705631526f757465723a204558434553534956455f494e505560448201527f545f414d4f554e5400000000000000000000000000000000000000000000000060648201526084016106b7565b7f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db08360008151811061334057613340615beb565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561337357600080fd5b505af1158015613387573d6000803e3d6000fd5b50505050507f000000000000000000000000fc0000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6133ff7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68989600081811061142e5761142e615beb565b8460008151811061341257613412615beb565b60200260200101516040518363ffffffff1660e01b815260040161345892919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015613477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349b9190615c57565b6134a7576134a761556c565b6134e682878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613ccd915050565b816000815181106134f9576134f9615beb565b6020026020010151341115611edb57611edb338360008151811061351f5761351f615beb565b60200260200101513461308b9190615bd8565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916135c99190615c98565b6000604051808303816000865af19150503d8060008114613606576040519150601f19603f3d011682016040523d82523d6000602084013e61360b565b606091505b50915091508180156136355750805115806136355750808060200190518101906136359190615c57565b6136c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016106b7565b5050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516136ff9190615c98565b60006040518083038185875af1925050503d806000811461373c576040519150601f19603f3d011682016040523d82523d6000602084013e613741565b606091505b50509050806137d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c656400000000000000000000000060648201526084016106b7565b505050565b606060028251101561386b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff81111561388557613885615756565b6040519080825280602002602001820160405280156138ae578160200160208202803683370190505b50905082816000815181106138c5576138c5615beb565b60200260200101818152505060005b600183516138e29190615bd8565b811015613a235760006139348685848151811061390157613901615beb565b6020026020010151868560016139179190615cb4565b8151811061392757613927615beb565b6020026020010151613a2b565b6040517f2e0ae37500000000000000000000000000000000000000000000000000000000815242600482015290915073ffffffffffffffffffffffffffffffffffffffff821690632e0ae37590602401600060405180830381600087803b15801561399e57600080fd5b505af11580156139b2573d6000803e3d6000fd5b505050506139f3818484815181106139cc576139cc615beb565b60200260200101518685815181106139e6576139e6615beb565b6020026020010151614efc565b836139ff846001615cb4565b81518110613a0f57613a0f615beb565b6020908102919091010152506001016138d4565b509392505050565b6000806000613a3a85856147ac565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015291935091508690604801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012083830183528184527f676b4c9b92980c4e7823b43031b17d7299896d1cd7d147104ad8e21692123fa1848301529151613aee94939101615cc7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209695505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691613bcd9190615c98565b6000604051808303816000865af19150503d8060008114613c0a576040519150601f19603f3d011682016040523d82523d6000602084013e613c0f565b606091505b5091509150818015613c39575080511580613c39575080806020019051810190613c399190615c57565b613cc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c656400000000000000000000000000000060648201526084016106b7565b505050505050565b60005b60018351613cde9190615bd8565b811015613ed257600080848381518110613cfa57613cfa615beb565b602002602001015185846001613d109190615cb4565b81518110613d2057613d20615beb565b6020026020010151915091506000613d3883836147ac565b509050600087613d49866001615cb4565b81518110613d5957613d59615beb565b602002602001015190506000808373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614613da157826000613da5565b6000835b91509150600060028a51613db99190615bd8565b8810613dc55788613df6565b613df67f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6878c6139178c6002615cb4565b9050613e237f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68888613a2b565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613e6d576020820181803683370190505b506040518563ffffffff1660e01b8152600401613e8d9493929190615d3f565b600060405180830381600087803b158015613ea757600080fd5b505af1158015613ebb573d6000803e3d6000fd5b505060019099019850613cd0975050505050505050565b50505050565b6060600282511015613f6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff811115613f8657613f86615756565b604051908082528060200260200182016040528015613faf578160200160208202803683370190505b509050828160018351613fc29190615bd8565b81518110613fd257613fd2615beb565b602002602001018181525050600060018351613fee9190615bd8565b90505b8015613a235760006140338685614009600186615bd8565b8151811061401957614019615beb565b602002602001015186858151811061392757613927615beb565b90508073ffffffffffffffffffffffffffffffffffffffff1663a1462c196040518163ffffffff1660e01b8152600401602060405180830381865afa158015614080573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140a49190615c57565b61410a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f7477616d6d206f7574206f66206461746500000000000000000000000000000060448201526064016106b7565b6141538184848151811061412057614120615beb565b6020026020010151866001866141369190615bd8565b8151811061414657614146615beb565b6020026020010151615150565b8361415f600185615bd8565b8151811061416f5761416f615beb565b6020908102919091010152508061418581615d84565b915050613ff1565b6060600282511015614221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff81111561423b5761423b615756565b604051908082528060200260200182016040528015614264578160200160208202803683370190505b5090508281600183516142779190615bd8565b8151811061428757614287615beb565b6020026020010181815250506000600183516142a39190615bd8565b90505b8015613a235760006142be8685614009600186615bd8565b6040517f2e0ae37500000000000000000000000000000000000000000000000000000000815242600482015290915073ffffffffffffffffffffffffffffffffffffffff821690632e0ae37590602401600060405180830381600087803b15801561432857600080fd5b505af115801561433c573d6000803e3d6000fd5b505050506143568184848151811061412057614120615beb565b83614362600185615bd8565b8151811061437257614372615beb565b6020908102919091010152508061438881615d84565b9150506142a6565b60005b600183516143a19190615bd8565b8110156137d2576000808483815181106143bd576143bd615beb565b6020026020010151858460016143d39190615cb4565b815181106143e3576143e3615beb565b60200260200101519150915060006143fb83836147ac565b509050600061442b7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68585613a2b565b90506000806000806000806144617f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68b8b6153a9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152949850929650909450925083918691908d16906370a0823190602401602060405180830381865afa1580156144dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145019190615c3e565b61450b9190615bd8565b6145159190615bd8565b955061452287878c614efc565b9450505050506000808573ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146145665782600061456a565b6000835b91509150600060028c5161457e9190615bd8565b8a1061458a578a6145bb565b6145bb7f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6898e6139178e6002615cb4565b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff87169063022c0d9f906146239086908690869060248101615d3f565b600060405180830381600087803b15801561463d57600080fd5b505af1158015614651573d6000803e3d6000fd5b50506001909b019a506143939950505050505050505050565b60008084116146fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4672617873776170526f757465724c6962726172793a20494e5355464649434960448201527f454e545f414d4f554e540000000000000000000000000000000000000000000060648201526084016106b7565b60008311801561470b5750600082115b614797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4672617873776170526f757465724c6962726172793a20494e5355464649434960448201527f454e545f4c49515549444954590000000000000000000000000000000000000060648201526084016106b7565b826147a28386615db9565b6120ce9190615dd0565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361486a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4672617873776170526f757465724c6962726172793a204944454e544943414c60448201527f5f4144445245535345530000000000000000000000000000000000000000000060648201526084016106b7565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16106148a45782846148a7565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff821661494f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a205a45524f5f4144445260448201527f455353000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b9250929050565b60606002825110156149ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4672617873776170526f757465724c6962726172793a20494e56414c49445f5060448201527f415448000000000000000000000000000000000000000000000000000000000060648201526084016106b7565b815167ffffffffffffffff811115614a0457614a04615756565b604051908082528060200260200182016040528015614a2d578160200160208202803683370190505b5090508281600081518110614a4457614a44615beb565b60200260200101818152505060005b60018351614a619190615bd8565b811015613a23576000614a808685848151811061390157613901615beb565b90508073ffffffffffffffffffffffffffffffffffffffff1663a1462c196040518163ffffffff1660e01b8152600401602060405180830381865afa158015614acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614af19190615c57565b614b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f7477616d6d206f7574206f66206461746500000000000000000000000000000060448201526064016106b7565b614b6d818484815181106139cc576139cc615beb565b83614b79846001615cb4565b81518110614b8957614b89615beb565b602090810291909101015250600101614a53565b6040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152600091829182917f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e69091169063e6a4390590604401602060405180830381865afa158015614c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c5e9190615e0b565b73ffffffffffffffffffffffffffffffffffffffff1603614d35576040517fc9c6539600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015288811660248301527f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6169063c9c65396906044016020604051808303816000875af1158015614d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d339190615e0b565b505b600080614d637f000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e68b8b6153a9565b505091509150816000148015614d77575080155b15614d8757879350869250614eef565b6000614d9489848461466a565b9050878111614e385785811015614e2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4260448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b889450925082614eed565b6000614e4589848661466a565b905089811115614e5757614e5761556c565b87811015614ee7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f46726178737761705631526f757465723a20494e53554646494349454e545f4160448201527f5f414d4f554e540000000000000000000000000000000000000000000000000060648201526084016106b7565b94508793505b505b5050965096945050505050565b6000808490506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015614f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f749190615e5a565b50915091506000808473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015614fc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614feb9190615e0b565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614615024578284615027565b83835b9150915060008811801561504b57506000826dffffffffffffffffffffffffffff16115b801561506757506000816dffffffffffffffffffffffffffff16115b61507057600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff1663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156150bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906150e19190615c3e565b6150eb908a615db9565b905060006151096dffffffffffffffffffffffffffff841683615db9565b905060008261512a6dffffffffffffffffffffffffffff8716612710615db9565b6151349190615cb4565b90506151408183615dd0565b9c9b505050505050505050505050565b6000808490506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156151a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906151c89190615e5a565b50915091506000808473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561521b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061523f9190615e0b565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161461527857838361527b565b82845b9150915060008811801561529f57506000826dffffffffffffffffffffffffffff16115b80156152bb57506000816dffffffffffffffffffffffffffff16115b6152c457600080fd5b60006152e0896dffffffffffffffffffffffffffff8516615db9565b6152ec90612710615db9565b905060008673ffffffffffffffffffffffffffffffffffffffff1663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa15801561533b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061535f9190615c3e565b6153798b6dffffffffffffffffffffffffffff8616615bd8565b6153839190615db9565b905061538f8183615dd0565b61539a906001615cb4565b9b9a5050505050505050505050565b60008060008060006153bb87876147ac565b50905060006153cb898989613a2b565b6040517f2e0ae37500000000000000000000000000000000000000000000000000000000815242600482015290915073ffffffffffffffffffffffffffffffffffffffff821690632e0ae37590602401600060405180830381600087803b15801561543557600080fd5b505af1158015615449573d6000803e3d6000fd5b505050506000806000808473ffffffffffffffffffffffffffffffffffffffff1663094cf1496040518163ffffffff1660e01b815260040160c060405180830381865afa15801561549e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906154c29190615e9d565b506dffffffffffffffffffffffffffff1694506dffffffffffffffffffffffffffff169450506dffffffffffffffffffffffffffff1693506dffffffffffffffffffffffffffff1693508573ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff1614615548578284828461554d565b838383835b809a50819b50829c50839d505050505050505050505093509350935093565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146155bd57600080fd5b50565b80356155cb8161559b565b919050565b60008060008060008060c087890312156155e957600080fd5b86356155f48161559b565b955060208701359450604087013593506060870135925060808701356156198161559b565b8092505060a087013590509295509295509295565b60008060006060848603121561564357600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261566c57600080fd5b50813567ffffffffffffffff81111561568457600080fd5b6020830191508360208260051b850101111561494f57600080fd5b60008060008060008060a087890312156156b857600080fd5b8635955060208701359450604087013567ffffffffffffffff8111156156dd57600080fd5b6156e989828a0161565a565b90955093505060608701356156fd8161559b565b80925050608087013590509295509295509295565b6020808252825182820181905260009190848201906040850190845b8181101561574a5783518352928401929184019160010161572e565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561579857600080fd5b8235915060208084013567ffffffffffffffff808211156157b857600080fd5b818601915086601f8301126157cc57600080fd5b8135818111156157de576157de615756565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561582157615821615756565b60405291825284820192508381018501918983111561583f57600080fd5b938501935b8285101561586457615855856155c0565b84529385019392850192615844565b8096505050505050509250929050565b80151581146155bd57600080fd5b803560ff811681146155cb57600080fd5b60008060008060008060008060008060006101608c8e0312156158b557600080fd5b8b356158c08161559b565b9a5060208c01356158d08161559b565b995060408c0135985060608c0135975060808c0135965060a08c01356158f58161559b565b955060c08c0135945060e08c013561590c81615874565b935061591b6101008d01615882565b92506101208c013591506101408c013590509295989b509295989b9093969950565b60005b83811015615958578181015183820152602001615940565b50506000910152565b6000815180845261597981602086016020860161593d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ca16020830184615961565b6000806000806000806000806000806101408b8d0312156159de57600080fd5b8a356159e98161559b565b995060208b0135985060408b0135975060608b0135965060808b0135615a0e8161559b565b955060a08b0135945060c08b0135615a2581615874565b9350615a3360e08c01615882565b92506101008b013591506101208b013590509295989b9194979a5092959850565b600080600080600060808688031215615a6c57600080fd5b85359450602086013567ffffffffffffffff811115615a8a57600080fd5b615a968882890161565a565b9095509350506040860135615aaa8161559b565b949793965091946060013592915050565b600080600080600080600060e0888a031215615ad657600080fd5b8735615ae18161559b565b96506020880135615af18161559b565b955060408801359450606088013593506080880135925060a0880135615b168161559b565b8092505060c0880135905092959891949750929550565b600080600080600080600080610100898b031215615b4a57600080fd5b8835615b558161559b565b97506020890135615b658161559b565b965060408901359550606089013594506080890135935060a0890135925060c0890135615b918161559b565b8092505060e089013590509295985092959890939650565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ca457610ca4615ba9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215615c2c57600080fd5b8135615c378161559b565b9392505050565b600060208284031215615c5057600080fd5b5051919050565b600060208284031215615c6957600080fd5b8151615c3781615874565b60008060408385031215615c8757600080fd5b505080516020909101519092909150565b60008251615caa81846020870161593d565b9190910192915050565b80820180821115610ca457610ca4615ba9565b7fff0000000000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008460601b16600182015282601582015260008251615d3081603585016020870161593d565b91909101603501949350505050565b84815283602082015273ffffffffffffffffffffffffffffffffffffffff83166040820152608060608201526000615d7a6080830184615961565b9695505050505050565b600081615d9357615d93615ba9565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610ca457610ca4615ba9565b600082615e06577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215615e1d57600080fd5b8151615c378161559b565b80516dffffffffffffffffffffffffffff811681146155cb57600080fd5b805163ffffffff811681146155cb57600080fd5b600080600060608486031215615e6f57600080fd5b615e7884615e28565b9250615e8660208501615e28565b9150615e9460408501615e46565b90509250925092565b60008060008060008060c08789031215615eb657600080fd5b615ebf87615e28565b9550615ecd60208801615e28565b9450615edb60408801615e46565b9350615ee960608801615e28565b9250615ef760808801615e28565b915060a08701519050929550929550929556
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6000000000000000000000000fc00000000000000000000000000000000000006
-----Decoded View---------------
Arg [0] : _factory (address): 0xE30521fe7f3bEB6Ad556887b50739d6C7CA667E6
Arg [1] : _WETH (address): 0xFC00000000000000000000000000000000000006
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000e30521fe7f3beb6ad556887b50739d6c7ca667e6
Arg [1] : 000000000000000000000000fc00000000000000000000000000000000000006
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.