Overview
ETH Balance
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
18307593 | 19 mins ago | 0 ETH | ||||
18307593 | 19 mins ago | 0 ETH | ||||
18307593 | 19 mins ago | 0 ETH | ||||
18307593 | 19 mins ago | 0 ETH | ||||
18307517 | 22 mins ago | 0.00449402 ETH | ||||
18307517 | 22 mins ago | 0 ETH | ||||
18307312 | 31 mins ago | 0.00353638 ETH | ||||
18307312 | 31 mins ago | 0 ETH | ||||
18306450 | 1 hr ago | 0 ETH | ||||
18304319 | 2 hrs ago | 0 ETH | ||||
18304277 | 2 hrs ago | 0 ETH | ||||
18303468 | 3 hrs ago | 0.15480992 ETH | ||||
18303468 | 3 hrs ago | 0 ETH | ||||
18303421 | 3 hrs ago | 0 ETH | ||||
18302584 | 3 hrs ago | 0 ETH | ||||
18302148 | 4 hrs ago | 0 ETH | ||||
18302138 | 4 hrs ago | 0.0182444 ETH | ||||
18302138 | 4 hrs ago | 0 ETH | ||||
18301393 | 4 hrs ago | 0.01852669 ETH | ||||
18301393 | 4 hrs ago | 0 ETH | ||||
18301190 | 4 hrs ago | 0 ETH | ||||
18301190 | 4 hrs ago | 0 ETH | ||||
18301108 | 4 hrs ago | 0.01061142 ETH | ||||
18300829 | 4 hrs ago | 0 ETH | ||||
18299903 | 5 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
Router
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 800 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "contracts/interfaces/IERC20.sol"; import "contracts/interfaces/IPair.sol"; import "contracts/interfaces/IPairFactory.sol"; import "contracts/interfaces/IRouter.sol"; import "contracts/interfaces/IWETH.sol"; contract Router is IRouter, Initializable { struct route { address from; address to; bool stable; } address public factory; address public timelock; IWETH public weth; uint256 internal constant MINIMUM_LIQUIDITY = 10 ** 3; bytes32 pairCodeHash; modifier onlyTimelock() { require(msg.sender == timelock, "!ADMIN"); _; } modifier ensure(uint256 deadline) { require(deadline >= block.timestamp, "EXPIRED"); _; } constructor() { _disableInitializers(); } function initialize( address _factory, address _weth, address _timelock ) external initializer { factory = _factory; pairCodeHash = IPairFactory(_factory).pairCodeHash(); weth = IWETH(_weth); timelock = _timelock; } receive() external payable { assert(msg.sender == address(weth)); // only accept ETH via fallback from the WETH contract } function sortTokens( address tokenA, address tokenB ) public pure returns (address token0, address token1) { require(tokenA != tokenB, "IDENTICAL"); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), "ZERO"); } /// calculates the CREATE2 address for a pair without making any external calls function pairFor( address tokenA, address tokenB, bool stable ) public view returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = address( uint160( uint256( keccak256( abi.encodePacked( hex"ff", factory, keccak256(abi.encodePacked(token0, token1, stable)), pairCodeHash // init code hash ) ) ) ) ); } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quoteLiquidity( uint256 amountA, uint256 reserveA, uint256 reserveB ) internal pure returns (uint256 amountB) { require(amountA > 0, "INSUFFICIENT AMOUNT"); require(reserveA > 0 && reserveB > 0, "INSUFFICIENT LIQUIDITY"); amountB = (amountA * reserveB) / reserveA; } // fetches and sorts the reserves for a pair function getReserves( address tokenA, address tokenB, bool stable ) public view returns (uint256 reserveA, uint256 reserveB) { (address token0, ) = sortTokens(tokenA, tokenB); (uint256 reserve0, uint256 reserve1, ) = IPair( pairFor(tokenA, tokenB, stable) ).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } // performs chained getAmountOut calculations on any number of pairs function getAmountOut( uint256 amountIn, address tokenIn, address tokenOut ) public view returns (uint256 amount, bool stable) { address pair = pairFor(tokenIn, tokenOut, true); uint256 amountStable; uint256 amountVolatile; if (IPairFactory(factory).isPair(pair)) { amountStable = IPair(pair).getAmountOut(amountIn, tokenIn); } pair = pairFor(tokenIn, tokenOut, false); if (IPairFactory(factory).isPair(pair)) { amountVolatile = IPair(pair).getAmountOut(amountIn, tokenIn); } return amountStable > amountVolatile ? (amountStable, true) : (amountVolatile, false); } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut( uint256 amountIn, route[] memory routes ) public view returns (uint256[] memory amounts) { require(routes.length >= 1, "INVALID PATH"); amounts = new uint256[](routes.length + 1); amounts[0] = amountIn; for (uint256 i = 0; i < routes.length; ++i) { address pair = pairFor( routes[i].from, routes[i].to, routes[i].stable ); if (IPairFactory(factory).isPair(pair)) { amounts[i + 1] = IPair(pair).getAmountOut( amounts[i], routes[i].from ); } } } function isPair(address pair) external view returns (bool) { return IPairFactory(factory).isPair(pair); } function quoteAddLiquidity( address tokenA, address tokenB, bool stable, uint256 amountADesired, uint256 amountBDesired ) external view returns (uint256 amountA, uint256 amountB, uint256 liquidity) { // create the pair if it doesn't exist yet address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable); (uint256 reserveA, uint256 reserveB) = (0, 0); uint256 _totalSupply = 0; if (_pair != address(0)) { _totalSupply = IERC20(_pair).totalSupply(); (reserveA, reserveB) = getReserves(tokenA, tokenB, stable); } if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); liquidity = Math.sqrt(amountA * amountB) - MINIMUM_LIQUIDITY; } else { uint256 amountBOptimal = quoteLiquidity( amountADesired, reserveA, reserveB ); if (amountBOptimal <= amountBDesired) { (amountA, amountB) = (amountADesired, amountBOptimal); liquidity = Math.min( (amountA * _totalSupply) / reserveA, (amountB * _totalSupply) / reserveB ); } else { uint256 amountAOptimal = quoteLiquidity( amountBDesired, reserveB, reserveA ); (amountA, amountB) = (amountAOptimal, amountBDesired); liquidity = Math.min( (amountA * _totalSupply) / reserveA, (amountB * _totalSupply) / reserveB ); } } } function quoteRemoveLiquidity( address tokenA, address tokenB, bool stable, uint256 liquidity ) external view returns (uint256 amountA, uint256 amountB) { // create the pair if it doesn't exist yet address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable); if (_pair == address(0)) { return (0, 0); } (uint256 reserveA, uint256 reserveB) = getReserves( tokenA, tokenB, stable ); uint256 _totalSupply = IERC20(_pair).totalSupply(); amountA = (liquidity * reserveA) / _totalSupply; // using balances ensures pro-rata distribution amountB = (liquidity * reserveB) / _totalSupply; // using balances ensures pro-rata distribution } function _addLiquidity( address tokenA, address tokenB, bool stable, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin ) internal returns (uint256 amountA, uint256 amountB) { require(amountADesired >= amountAMin); require(amountBDesired >= amountBMin); // create the pair if it doesn't exist yet address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable); if (_pair == address(0)) { _pair = IPairFactory(factory).createPair(tokenA, tokenB, stable); } (uint256 reserveA, uint256 reserveB) = getReserves( tokenA, tokenB, stable ); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint256 amountBOptimal = quoteLiquidity( amountADesired, reserveA, reserveB ); if (amountBOptimal <= amountBDesired) { require(amountBOptimal >= amountBMin, "INSUFFICIENT B"); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint256 amountAOptimal = quoteLiquidity( amountBDesired, reserveB, reserveA ); assert(amountAOptimal <= amountADesired); require(amountAOptimal >= amountAMin, "INSUFFICIENT A"); (amountA, amountB) = (amountAOptimal, amountBDesired); } } } function addLiquidity( address tokenA, address tokenB, bool stable, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) { (amountA, amountB) = _addLiquidity( tokenA, tokenB, stable, amountADesired, amountBDesired, amountAMin, amountBMin ); address pair = pairFor(tokenA, tokenB, stable); _safeTransferFrom(tokenA, msg.sender, pair, amountA); _safeTransferFrom(tokenB, msg.sender, pair, amountB); liquidity = IPair(pair).mint(to); } function addLiquidityETH( address token, bool stable, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable ensure(deadline) returns (uint256 amountToken, uint256 amountETH, uint256 liquidity) { (amountToken, amountETH) = _addLiquidity( token, address(weth), stable, amountTokenDesired, msg.value, amountTokenMin, amountETHMin ); address pair = pairFor(token, address(weth), stable); _safeTransferFrom(token, msg.sender, pair, amountToken); weth.deposit{value: amountETH}(); assert(weth.transfer(pair, amountETH)); liquidity = IPair(pair).mint(to); // refund dust eth, if any if (msg.value > amountETH) _safeTransferETH(msg.sender, msg.value - amountETH); } // **** REMOVE LIQUIDITY **** function removeLiquidity( address tokenA, address tokenB, bool stable, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) public ensure(deadline) returns (uint256 amountA, uint256 amountB) { address pair = pairFor(tokenA, tokenB, stable); require(IPair(pair).transferFrom(msg.sender, pair, liquidity)); // send liquidity to pair (uint256 amount0, uint256 amount1) = IPair(pair).burn(to); (address token0, ) = sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); require(amountA >= amountAMin, "INSUFFICIENT A"); require(amountB >= amountBMin, "INSUFFICIENT B"); } function removeLiquidityETH( address token, bool stable, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) public ensure(deadline) returns (uint256 amountToken, uint256 amountETH) { (amountToken, amountETH) = removeLiquidity( token, address(weth), stable, liquidity, amountTokenMin, amountETHMin, address(this), deadline ); _safeTransfer(token, to, amountToken); weth.withdraw(amountETH); _safeTransferETH(to, amountETH); } function removeLiquidityWithPermit( address tokenA, address tokenB, bool stable, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB) { address pair = pairFor(tokenA, tokenB, stable); { uint256 value = approveMax ? type(uint256).max : liquidity; IPair(pair).permit( msg.sender, address(this), value, deadline, v, r, s ); } (amountA, amountB) = removeLiquidity( tokenA, tokenB, stable, liquidity, amountAMin, amountBMin, to, deadline ); } function removeLiquidityETHWithPermit( address token, bool stable, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH) { address pair = pairFor(token, address(weth), stable); uint256 value = approveMax ? type(uint256).max : liquidity; IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountToken, amountETH) = removeLiquidityETH( token, stable, liquidity, amountTokenMin, amountETHMin, to, deadline ); } // **** SWAP **** // requires the initial amount to have already been sent to the first pair function _swap( uint256[] memory amounts, route[] memory routes, address _to ) internal virtual { for (uint256 i = 0; i < routes.length; ++i) { (address token0, ) = sortTokens(routes[i].from, routes[i].to); uint256 amountOut = amounts[i + 1]; (uint256 amount0Out, uint256 amount1Out) = routes[i].from == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0)); address to = i < routes.length - 1 ? pairFor( routes[i + 1].from, routes[i + 1].to, routes[i + 1].stable ) : _to; IPair(pairFor(routes[i].from, routes[i].to, routes[i].stable)).swap( amount0Out, amount1Out, to, new bytes(0) ); } } function swapExactTokensForTokensSimple( uint256 amountIn, uint256 amountOutMin, address tokenFrom, address tokenTo, bool stable, address to, uint256 deadline ) external ensure(deadline) returns (uint256[] memory amounts) { route[] memory routes = new route[](1); routes[0].from = tokenFrom; routes[0].to = tokenTo; routes[0].stable = stable; amounts = getAmountsOut(amountIn, routes); require( amounts[amounts.length - 1] >= amountOutMin, "INSUFFICIENT OUTPUT" ); _safeTransferFrom( routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0] ); _swap(amounts, routes, to); } function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, route[] calldata routes, address to, uint256 deadline ) external ensure(deadline) returns (uint256[] memory amounts) { amounts = getAmountsOut(amountIn, routes); require( amounts[amounts.length - 1] >= amountOutMin, "INSUFFICIENT OUTPUT" ); _safeTransferFrom( routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0] ); _swap(amounts, routes, to); } function swapExactETHForTokens( uint256 amountOutMin, route[] calldata routes, address to, uint256 deadline ) external payable ensure(deadline) returns (uint256[] memory amounts) { require(routes[0].from == address(weth), "INVALID PATH"); amounts = getAmountsOut(msg.value, routes); require( amounts[amounts.length - 1] >= amountOutMin, "INSUFFICIENT OUTPUT" ); weth.deposit{value: amounts[0]}(); assert( weth.transfer( pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0] ) ); _swap(amounts, routes, to); } function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, route[] calldata routes, address to, uint256 deadline ) external ensure(deadline) returns (uint256[] memory amounts) { require(routes[routes.length - 1].to == address(weth), "INVALID PATH"); amounts = getAmountsOut(amountIn, routes); require( amounts[amounts.length - 1] >= amountOutMin, "INSUFFICIENT OUTPUT" ); _safeTransferFrom( routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0] ); _swap(amounts, routes, address(this)); weth.withdraw(amounts[amounts.length - 1]); _safeTransferETH(to, amounts[amounts.length - 1]); } function UNSAFE_swapExactTokensForTokens( uint256[] memory amounts, route[] calldata routes, address to, uint256 deadline ) external ensure(deadline) returns (uint256[] memory) { _safeTransferFrom( routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0] ); _swap(amounts, routes, to); return amounts; } function _safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, "ETH TRANSFER FAILED"); } function _safeTransfer(address token, address to, uint256 value) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call( abi.encodeWithSelector(IERC20.transfer.selector, to, value) ); require(success && (data.length == 0 || abi.decode(data, (bool)))); } function _safeTransferFrom( address token, address from, address to, uint256 value ) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call( abi.encodeWithSelector( IERC20.transferFrom.selector, from, to, value ) ); require(success && (data.length == 0 || abi.decode(data, (bool)))); } /// @notice recovers user funds transferred to router by mistake /// @dev it's doesn't create a security issue because no asset is supposed to be in the router. function recoverFunds( address token, address to, uint256 amount ) external onlyTimelock { _safeTransfer(token, to, amount); } // Experimental Extension [ETH.guru/solidly/BaseV1Router02] // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens)**** function removeLiquidityETHSupportingFeeOnTransferTokens( address token, bool stable, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) public ensure(deadline) returns (uint256 amountToken, uint256 amountETH) { (amountToken, amountETH) = removeLiquidity( token, address(weth), stable, liquidity, amountTokenMin, amountETHMin, address(this), deadline ); _safeTransfer(token, to, IERC20(token).balanceOf(address(this))); weth.withdraw(amountETH); _safeTransferETH(to, amountETH); } function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, bool stable, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH) { address pair = pairFor(token, address(weth), stable); uint256 value = approveMax ? type(uint256).max : liquidity; IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); ( amountToken, amountETH ) = removeLiquidityETHSupportingFeeOnTransferTokens( token, stable, liquidity, amountTokenMin, amountETHMin, to, deadline ); } // **** SWAP (supporting fee-on-transfer tokens) **** // requires the initial amount to have already been sent to the first pair function _swapSupportingFeeOnTransferTokens( route[] calldata routes, address _to ) internal virtual { for (uint256 i; i < routes.length; i++) { (address input, address output) = (routes[i].from, routes[i].to); (address token0, ) = sortTokens(input, output); IPair pair = IPair( pairFor(routes[i].from, routes[i].to, routes[i].stable) ); uint256 amountInput; uint256 amountOutput; { // scope to avoid stack too deep errors (uint256 reserve0, uint256 reserve1, ) = pair.getReserves(); (uint256 reserveInput, ) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput; (amountOutput, ) = getAmountOut(amountInput, input, output); } (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOutput) : (amountOutput, uint256(0)); address to = i < routes.length - 1 ? pairFor( routes[i + 1].from, routes[i + 1].to, routes[i + 1].stable ) : _to; pair.swap(amount0Out, amount1Out, to, new bytes(0)); } } function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, route[] calldata routes, address to, uint256 deadline ) external ensure(deadline) { _safeTransferFrom( routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn ); uint256 balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf( to ); _swapSupportingFeeOnTransferTokens(routes, to); require( IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >= amountOutMin, "INSUFFICIENT OUTPUT" ); } function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, route[] calldata routes, address to, uint256 deadline ) external payable ensure(deadline) { require(routes[0].from == address(weth), "INVALID PATH"); uint256 amountIn = msg.value; weth.deposit{value: amountIn}(); assert( weth.transfer( pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn ) ); uint256 balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf( to ); _swapSupportingFeeOnTransferTokens(routes, to); require( IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >= amountOutMin, "INSUFFICIENT OUTPUT" ); } function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, route[] calldata routes, address to, uint256 deadline ) external ensure(deadline) { require(routes[routes.length - 1].to == address(weth), "INVALID PATH"); _safeTransferFrom( routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn ); _swapSupportingFeeOnTransferTokens(routes, address(this)); uint256 amountOut = IERC20(address(weth)).balanceOf(address(this)); require(amountOut >= amountOutMin, "INSUFFICIENT OUTPUT"); weth.withdraw(amountOut); _safeTransferETH(to, amountOut); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/Address.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IERC20 { function totalSupply() external view returns (uint256); function transfer( address recipient, uint256 amount ) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint256); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); function allowance( address owner, address spender ) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); function name() external view returns (string memory); function burn(uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13 || =0.7.6; interface IPair { function initialize( address _factory, address _token0, address _token1, bool _stable, address _voter ) external; function metadata() external view returns ( uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, bool st, address t0, address t1 ); function claimFees() external returns (uint256, uint256); function tokens() external view returns (address, address); function transferFrom( address src, address dst, uint256 amount ) external returns (bool); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function burn( address to ) external returns (uint256 amount0, uint256 amount1); function mint(address to) external returns (uint256 liquidity); function getReserves() external view returns ( uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast ); function getAmountOut( uint256 amountIn, address tokenIn ) external view returns (uint256); function symbol() external view returns (string memory); function fees() external view returns (address); function setActiveGauge(bool isActive) external; function setFeeSplit() external; function feeSplit() external view returns (uint8 _feeSplit); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IPairFactory { function allPairsLength() external view returns (uint256); function isPair(address pair) external view returns (bool); function pairCodeHash() external view returns (bytes32); function getPair( address tokenA, address token, bool stable ) external view returns (address); function createPair( address tokenA, address tokenB, bool stable ) external returns (address pair); function voter() external view returns (address); function allPairs(uint256) external view returns (address); function pairFee(address) external view returns (uint256); function getFee(bool) external view returns (uint256); function isPaused() external view returns (bool); function setFeeManager(address _feeManager) external; function setPairFee(address _pair, uint256 _fee) external; function setFee(bool _stable, uint256 _fee) external; function treasury() external view returns (address); function feeSplit() external view returns (uint8); function getPoolFeeSplit( address _pool ) external view returns (uint8 _poolFeeSplit); function setFeeSplit(uint8 _toFees, uint8 _toTreasury) external; function setPoolFeeSplit( address _pool, uint8 _toFees, uint8 _toTreasury ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IRouter { function pairFor( address tokenA, address tokenB, bool stable ) external view returns (address pair); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; function approve(address spender, uint256 value) external returns (bool); }
{ "optimizer": { "enabled": true, "runs": 800 }, "evmVersion": "paris", "viaIR": true, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"UNSAFE_swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"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":"bool","name":"stable","type":"bool"},{"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":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"stable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"getReserves","outputs":[{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_timelock","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"pairFor","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"}],"name":"quoteAddLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"quoteRemoveLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"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":"bool","name":"stable","type":"bool"},{"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":"bool","name":"stable","type":"bool"},{"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":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"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":"bool","name":"stable","type":"bool"},{"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":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"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":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"sortTokens","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"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"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"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"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"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"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"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"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"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":"tokenFrom","type":"address"},{"internalType":"address","name":"tokenTo","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSimple","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60808060405234620000c6576000549060ff8260081c1662000074575060ff8082160362000038575b60405161386a9081620000cc8239f35b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a13862000028565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b600080fdfe604060808152600480361015610035575b5050361561001d57600080fd5b6100336001600160a01b03600254163314612cf7565b005b600090813560e01c80630dede6c41461204457806313dcfc5914611eb957806318a1308614611d075780633fc8cef314611cdf5780634386e63c14611ca6578063448725b414611bb05780634c1ee03e14611b6f578063544caa5614611b2b5780635a47ddc314611a0c5780635d3590d5146119845780635e1e6325146119475780635e60dab51461191257806367ffb66a146117645780636cc1ae13146116c15780637301e3c81461160e57806376c72751146113955780637af728c8146111e15780639881fcb41461118357806398a0fb3c14610f2d578063a32b1fcd14610cd8578063b7e0d4c014610b01578063c0c53b8b146108b7578063c45a01551461088e578063d33219b414610866578063d7b0e0a514610666578063e2d9d4dc14610583578063e5e31b13146104fa578063f41766d8146103ff5763fe411f14146101815750610010565b346103fb5761018f3661241a565b979395909491969297421115966101a588612468565b6101c66001600160a01b03936101bf85600254169a612468565b8984612806565b8a516323b872dd60e01b8152338682019081526001600160a01b038316602082810191909152604082019a909a529185169189908290819060600103818a865af19081156103f15787916103c4575b50156103af57908a8692602482518095819363226bf2d160e21b8352308b8401525af19889156103ba578692879a61037e575b50610253908461289d565b5083851692908516830361036957916102808992610278602496959d8e5b10156124cc565b8b1015612518565b8b516370a0823160e01b8152308782015293849182905afa90811561035f5786908692610327575b6102b293506133b4565b6002541690813b15610323578560248492838b519586948593632e1a7d4d60e01b85528401525af1801561031957908592916102fe575b50506102f4916131d1565b8351928352820152f35b81925061030a906122fc565b610316578084916102e9565b80fd5b87513d84823e3d90fd5b8280fd5b9150508682813d8311610358575b61033f8183612348565b8101031261035357856102b29251916102a8565b600080fd5b503d610335565b8a513d87823e3d90fd5b98916102808992610278602496959d8e610271565b8c80929b508194503d83116103b3575b6103988183612348565b810103126103af5781519188015198610253610248565b8580fd5b503d61038e565b8b513d88823e3d90fd5b6103e49150893d8b116103ea575b6103dc8183612348565b8101906124b4565b38610215565b503d6103d2565b8c513d89823e3d90fd5b5080fd5b5091346103fb57610439610428610415366121ba565b9893989692959096949194421115612468565b610433368587612382565b90612d14565b95865160001981019081116104e7579061045661045e9289612587565b5110156125be565b81156104d4576104d086866104c6876104c088886104b961047e8361261a565b6104a761048a8561261a565b6104966020870161261a565b6104a18b880161267a565b91612806565b6104b08a612564565b51913390612f50565b3691612382565b8461305c565b519182918261214d565b0390f35b634e487b7160e01b815260328752602490fd5b634e487b7160e01b835260118952602483fd5b5082346103235760203660031901126103235760206105176120d2565b60246001600160a01b039182875460101c168551968794859363e5e31b1360e01b855216908301525afa918215610579576020939261055a575b50519015158152f35b610572919250833d85116103ea576103dc8183612348565b9083610551565b81513d85823e3d90fd5b50346103fb5761059236612209565b9593926001600160a01b039c989a95999b979c966105b58d896002541689612806565b911561065e5787600019925b1692833b1561065a578f5163d505accf60e01b815233818c0190815230602082015260408101949094526060840187905260ff909516608084015260a083015260c08201528891839182908490829060e00103925af180156103f157908791610646575b50506101c690421115986106388a612468565b6101bf85600254169a612468565b61064f906122fc565b6103af578538610625565b8a80fd5b878c926105c1565b50829034610323576106773661241a565b989492969398959190954211159861068e8a612468565b6106f060206106b46001600160a01b03966106ad88600254169e612468565b8d87612806565b8b516323b872dd60e01b8152338982019081526001600160a01b0383166020820152604081019590955290871693909283918291606090910190565b03818a865af190811561085c57879161083d575b50156103af57888691602482518094819363226bf2d160e21b8352308b8401525af1998a15610833578691879b6107f9575b509261076d999a9288928661074e61077a978561289d565b5016878416146000146107ea5790610775919b8c959b5b8610156124cc565b8a1015612518565b6133b4565b6002541690813b15610323578460248492838a519586948593632e1a7d4d60e01b85528401525af180156107e057908492916107c8575b50506107bc916131d1565b82519182526020820152f35b8192506107d4906122fc565b610316578083916107b1565b86513d84823e3d90fd5b9390610775919b8c959b610765565b8a80929c508193503d831161082c575b6108138183612348565b810103126103af5780516020909101519961077a610736565b503d610809565b89513d88823e3d90fd5b610856915060203d6020116103ea576103dc8183612348565b8b610704565b8a513d89823e3d90fd5b8284346103fb57816003193601126103fb576020906001600160a01b03600154169051908152f35b8284346103fb57816003193601126103fb576001600160a01b036020925460101c169051908152f35b508234610323576060366003190112610323576108d26120d2565b906108db6120e8565b6108e3612114565b9085549160ff8360081c161592838094610af4575b8015610add575b15610a745760ff198116600117885583610a63575b506001600160a01b039081602089549775ffffffffffffffffffffffffffffffffffffffff00008160101b16998a7fffffffffffffffffffff0000000000000000000000000000000000000000ffff8b16178c55885180948193631355724960e31b8352165afa908115610a59578991610a23575b50600355817fffffffffffffffffffffffff00000000000000000000000000000000000000009316836002541617600255169060015416176001556109cc578380f35b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498927fffffffffffffffffffff000000000000000000000000000000000000000000ff602093161784555160018152a18180808380f35b90506020813d602011610a51575b81610a3e60209383612348565b81010312610a4d575189610989565b8880fd5b3d9150610a31565b86513d8b823e3d90fd5b61ffff191661010117875587610914565b845162461bcd60e51b8152602081890152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608490fd5b50303b1580156108ff5750600160ff8216146108ff565b50600160ff8216106108f8565b50610b5c91610b5393610b45610b2d610b193661241a565b9b949b979396909597929192421115612468565b6001600160a01b03958660025416908c34928a61323d565b998199856002541687612806565b80953390612f50565b8160025416803b156103af5785899188875180948193630d0e30db60e41b83525af18015610cce57908691610cb6575b50600254855163a9059cbb60e01b81526001600160a01b03861689820190815260208082018d905296939192879284928390036040019183919089165af1908115610cac5784602493610beb889796948b948591610c8f575b50612cf7565b88519a8b9687956335313c2160e11b87521690850152165af1928315610c845792610c52575b506104d09250843411610c3a575b51938493846040919493926060820195825260208201520152565b610c4d610c47863461259b565b336131d1565b610c1f565b90915082813d8311610c7d575b610c698183612348565b81010312610353576104d091519038610c11565b503d610c5f565b8251903d90823e3d90fd5b610ca69150893d8b116103ea576103dc8183612348565b38610be5565b86513d89823e3d90fd5b610cbf906122fc565b610cca578438610b8c565b8480fd5b85513d88823e3d90fd5b50346103fb576101803660031901126103fb57610cf36120d2565b610cfb6120e8565b92610d0461213e565b90606435610d106120fe565b9060e4359361010435948515158603610353576101243560ff8116810361035357610d3c838b8a612806565b9615610f2657600019905b6001600160a01b0380981690813b15610f22578c5163d505accf60e01b815233818d0190815230602082015260408101949094526060840185905260ff90911660808401526101443560a08401526101643560c0840152918791839182908490829060e00103925af180156103ba57908691610f0e575b5050610ddc610e1892610dd5602093421115612468565b8a89612806565b8a516323b872dd60e01b8152338a82019081526001600160a01b0383166020820152604081019590955290871693909283918291606090910190565b038187865af1908115610f04578491610ee5575b501561032357602488928486938551998a95869463226bf2d160e21b865216908401525af1948515610ed95781948296610e9f575b5090610e6e83928561289d565b50905016911614600014610e9a57905b610e8c6084358310156124cc565b6107bc60a435821015612518565b610e7e565b87809297508196503d8311610ed2575b610eb98183612348565b8101031261031657835160209094015194610e6e610e61565b503d610eaf565b508551903d90823e3d90fd5b610efe915060203d6020116103ea576103dc8183612348565b38610e2c565b89513d86823e3d90fd5b610f17906122fc565b610cca578438610dbe565b8780fd5b8390610d47565b509190346103165760a036600319011261031657610f496120d2565b91610f526120e8565b91610f5b61213e565b936064359360843595826001600160a01b039182865460101c16938a885180966306801cc360e41b82528180610fb8878760209d8e98850191939260409160608401956001600160a01b0380921685521660208401521515910152565b03915afa94851561117957908b9291889661114a575b5087968895899716806110cb575b5050505050508215806110c3575b1561104157505050611004610fff85856126a6565b61371a565b6103e71981019190821161102e575090519182526020820192909252604081019190915260609150f35b634e487b7160e01b815260118652602490fd5b909592919650611052818887613666565b9280841161109a5750611081906110766104d0969761107b869a611076838c6126a6565b6126b9565b956126a6565b90508082101561109357505b90610c1f565b905061108d565b92506104d09450806110766110b3896110819487613666565b9761107b869a611076838c6126a6565b508015610fea565b91949750929550829194508851958680926318160ddd60e01b82525afa908115611140578691611110575b50611102935093612c55565b919091388881808080610fdc565b905083813d8311611139575b6111268183612348565b81010312610353576111029251386110f6565b503d61111c565b87513d88823e3d90fd5b61116b919650873d8911611172575b6111638183612348565b810190612687565b9438610fce565b503d611159565b88513d89823e3d90fd5b509190346103165781600319360112610316576024359067ffffffffffffffff8211610316573660238301121561031657506104d0926111cf6111d69236906024818501359101612382565b9035612d14565b90519182918261214d565b5091346103fb576112026111f4366121ba565b969493959096421115612468565b6000198101818111611382579061122c61122696959493926020978891848661260a565b0161261a565b926112476001600160a01b039485806002541691161461262e565b811561136f5782899695949261128f611296936112648e9761261a565b6112878c61127c6112748861261a565b91880161261a565b6104a18c890161267a565b903390612f50565b30916133fc565b600254169282516370a0823160e01b815230838201528681602481885afa96871561136557869761132f575b50506112d0908610156125be565b823b1561132b5784602485928385519687948593632e1a7d4d60e01b85528401525af1908115611322575061130e575b505061130b916131d1565b80f35b611317906122fc565b610323578284611300565b513d84823e3d90fd5b8380fd5b809297508196503d831161135e575b6113488183612348565b81010312610353576112d08794519590896112c2565b503d61133e565b84513d88823e3d90fd5b634e487b7160e01b895260328a52602489fd5b634e487b7160e01b885260118952602488fd5b506113b3836113a33661227e565b9692969590919395421115612468565b82156115fb57906113e191876113c88861261a565b6002546001600160a01b0395908616918616821461262e565b803b156103fb57818491885192838092630d0e30db60e41b825234905af18015610319576115e7575b509261143e9381600254166114716114218b61261a565b9160209788938d6104a18d61143788840161261a565b920161267a565b8a5163a9059cbb60e01b81526001600160a01b039091168882019081523460208201529094859384928391604090910190565b03925af19081156115dd579061148d918b916115c05750612cf7565b60001985018581116115ad57816114a986611226848a8e61260a565b16958751996370a0823160e01b94858c52878c6024818885169c8d8c8301525afa9b8c156115a3578d9c611566575b506112268897969484846114f48b9560249a986114f9986133fc565b61260a565b168751968794859384528301525afa92831561155d5750859261152d575b505061130b926115269161259b565b10156125be565b90809250813d8311611556575b6115448183612348565b81010312610353575182611526611517565b503d61153a565b513d87823e3d90fd5b909695939b508781819694963d831161159c575b6115848183612348565b8101031261035357519a9495929491939192876114d8565b503d61157a565b8a513d8f823e3d90fd5b634e487b7160e01b8a526011845260248afd5b6115d79150863d88116103ea576103dc8183612348565b8b610be5565b87513d8c823e3d90fd5b6115f0906122fc565b610f2257878961140a565b634e487b7160e01b875260328252602487fd5b5091346103fb5760803660031901126103fb5782359167ffffffffffffffff8084116103fb57366023850112156103fb578385013561164c8161236a565b9461165985519687612348565b8186526020916024602088019160051b830101913683116103af57602401905b8282106116b257505050506024359081116103fb5761169b9036908601612189565b6116a3612114565b9261045e426064351015612468565b81358152908301908301611679565b508234610323576116e6906116d5366121ba565b979297969091949396421115612468565b8315611751576117196116f88861261a565b936117028961261a565b946112876020968b6104a18b6114378b840161261a565b600019840184811161173e576001600160a01b0390816114a986611226848a8e61260a565b634e487b7160e01b895260118352602489fd5b634e487b7160e01b885260328252602488fd5b50826117826117723661227e565b9691929396949094421115612468565b81156118ff576117ad6117948461261a565b6002546001600160a01b0392908316918316821461262e565b6117c16117bb368688612382565b34612d14565b97885160001981019081116118ec578a92916104566117e0928c612587565b6117e989612564565b5190803b15610323578290858a5180948193630d0e30db60e41b83525af180156118e2576118ce575b505061187d916020916002541661184161182b8761261a565b61183685890161261a565b6104a18b8a0161267a565b8a61184b8b612564565b518a5163a9059cbb60e01b81526001600160a01b03909316948301948552602085015290948593849291839160400190565b03925af19081156118c457916104b96104c69594926104c0946104d09a916118a55750612cf7565b6118be915060203d6020116103ea576103dc8183612348565b8a610be5565b85513d89823e3d90fd5b6118d7906122fc565b610f22578789611812565b88513d84823e3d90fd5b634e487b7160e01b8b526011855260248bfd5b634e487b7160e01b875260329052602486fd5b50503461031657606036600319011261031657506107bc6119316120d2565b6119396120e8565b61194161213e565b91612c55565b5090346103165760603660031901126103165750611976906119676120e8565b61196f612114565b913561293c565b825191825215156020820152f35b50346103fb5760603660031901126103fb5761199e6120d2565b906119a76120e8565b906001600160a01b036001541633036119c957509061130b91604435916133b4565b606490602086519162461bcd60e51b8352820152600660248201527f2141444d494e00000000000000000000000000000000000000000000000000006044820152fd5b509190346103165761012036600319011261031657611a296120d2565b90611a326120e8565b92611a3b61213e565b9260e4356001600160a01b0380821680920361035357611aa59785602492611aac611a9a602097611a8c8c8e611a7642610104351015612468565b60c4359160a4359160843591606435918761323d565b9e8f93829f929e8385612806565b9d8e80943390612f50565b3390612f50565b865198899586946335313c2160e11b8652850152165af1918215611b205791611aea575b519283526020830193909352506040810191909152606090f35b90506020823d602011611b18575b81611b0560209383612348565b81010312610353576104d0915190611ad0565b3d9150611af8565b9051903d90823e3d90fd5b50503461031657816003193601126103165750611b57611b496120d2565b611b516120e8565b9061289d565b82516001600160a01b03928316815291166020820152f35b8284346103fb5760603660031901126103fb576020906001600160a01b03611ba8611b986120d2565b611ba06120e8565b6104a161213e565b915191168152f35b5082903461032357611bc136612209565b92899d99979b989493611be56001600160a01b039c98979c998a600254168a612806565b9115611c9e5788600019925b1692833b15611c9a578e5163d505accf60e01b815233818d0190815230602082015260408101949094526060840187905260ff909516608084015260a083015260c08201528991839182908490829060e00103925af18015611c9057611c78575b5060206106b4611c6a9c6106f0934211159d8e612468565b6106ad88600254169e612468565b611c8288916122fc565b611c8c578b611c52565b8680fd5b8b513d8a823e3d90fd5b8b80fd5b888692611bf1565b50503461031657608036600319011261031657506107bc611cc56120d2565b611ccd6120e8565b611cd561213e565b90606435926126d9565b8284346103fb57816003193601126103fb576020906001600160a01b03600254169051908152f35b5091346103fb57611d2b611d1a366121ba565b979397959095949294421115612468565b60001993818501828111611ea657611d4c6020611226611d7293868661260a565b93611d676001600160a01b039586806002541691161461262e565b610433368585612382565b978851868101908111611e935790610456611d8d928b612587565b8115611e805790611ddd82611dd4611da7611de39561261a565b611dcb611db38461261a565b8c6104a1611dc36020880161261a565b91870161267a565b6104b08d612564565b30923691612382565b8861305c565b600254168551838101908111611e6d57611dfd9087612587565b51813b156103235782916024839288519485938492632e1a7d4d60e01b84528d8401525af18015611e6357611e54575b50845191820191821161102e576104d085856104c686611e4d8785612587565b51906131d1565b611e5d906122fc565b38611e2d565b85513d84823e3d90fd5b634e487b7160e01b835260118852602483fd5b634e487b7160e01b845260328952602484fd5b634e487b7160e01b865260118b52602486fd5b634e487b7160e01b855260118a52602485fd5b5082346103235760e036600319011261032357611ed4612114565b606435926001600160a01b03908185168095036103af5760843591821515809303611c8c5760a435908082168203610f2257611f144260c4351015612468565b85519386850185811067ffffffffffffffff82111761203157875260018552885b602080821015611f6657885160209291611f4e826122ca565b8c82528c818301528c8b830152828901015201611f35565b50509194979690929783611f7986612564565b51911690526020611f8985612564565b51015284611f9684612564565b510152611fa4828735612d14565b80519095600019820191821161201e576104d087876104c688886104c089611fd26024356104568c8a612587565b61201581611fdf85612564565b5151169180611fed86612564565b515116906020611ffc87612564565b510151168861200a87612564565b510151151591612806565b6104b088612564565b634e487b7160e01b815260118852602490fd5b634e487b7160e01b8a526041855260248afd5b50346103fb576101003660031901126103fb5761205f6120d2565b6120676120e8565b9261207061213e565b9061209261207c6120fe565b9261208b4260e4351015612468565b8685612806565b86516323b872dd60e01b8152338682019081526001600160a01b039283166020828101829052606435604084015293959390929182908190606001610e18565b600435906001600160a01b038216820361035357565b602435906001600160a01b038216820361035357565b60c435906001600160a01b038216820361035357565b604435906001600160a01b038216820361035357565b35906001600160a01b038216820361035357565b60443590811515820361035357565b602090602060408183019282815285518094520193019160005b828110612175575050505090565b835185529381019392810192600101612167565b9181601f840112156103535782359167ffffffffffffffff8311610353576020808501946060850201011161035357565b60a06003198201126103535760043591602435916044359067ffffffffffffffff8211610353576121ed91600401612189565b90916064356001600160a01b0381168103610353579060843590565b610160906003190112610353576001600160a01b0390600435828116810361035357916024358015158103610353579160443591606435916084359160a4359081168103610353579060c4359060e435801515810361035357906101043560ff81168103610353579061012435906101443590565b90608060031983011261035357600435916024359067ffffffffffffffff8211610353576122ae91600401612189565b90916044356001600160a01b0381168103610353579060643590565b6060810190811067ffffffffffffffff8211176122e657604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116122e657604052565b6080810190811067ffffffffffffffff8211176122e657604052565b6020810190811067ffffffffffffffff8211176122e657604052565b90601f8019910116810190811067ffffffffffffffff8211176122e657604052565b67ffffffffffffffff81116122e65760051b60200190565b92919261238e8261236a565b60409461239e6040519283612348565b8195848352602080930191606080960285019481861161035357925b8584106123ca5750505050505050565b8684830312610353578251906123df826122ca565b6123e88561212a565b82526123f586860161212a565b868301528385013590811515820361035357828792868b9501528152019301926123ba565b60e0906003190112610353576001600160a01b0390600435828116810361035357916024358015158103610353579160443591606435916084359160a4359081168103610353579060c43590565b1561246f57565b60405162461bcd60e51b815260206004820152600760248201527f45585049524544000000000000000000000000000000000000000000000000006044820152606490fd5b90816020910312610353575180151581036103535790565b156124d357565b60405162461bcd60e51b815260206004820152600e60248201527f494e53554646494349454e5420410000000000000000000000000000000000006044820152606490fd5b1561251f57565b60405162461bcd60e51b815260206004820152600e60248201527f494e53554646494349454e5420420000000000000000000000000000000000006044820152606490fd5b8051156125715760200190565b634e487b7160e01b600052603260045260246000fd5b80518210156125715760209160051b010190565b919082039182116125a857565b634e487b7160e01b600052601160045260246000fd5b156125c557565b60405162461bcd60e51b815260206004820152601360248201527f494e53554646494349454e54204f5554505554000000000000000000000000006044820152606490fd5b9190811015612571576060020190565b356001600160a01b03811681036103535790565b1561263557565b60405162461bcd60e51b815260206004820152600c60248201527f494e56414c4944205041544800000000000000000000000000000000000000006044820152606490fd5b3580151581036103535790565b9081602091031261035357516001600160a01b03811681036103535790565b818102929181159184041417156125a857565b81156126c3570490565b634e487b7160e01b600052601260045260246000fd5b600080546040516306801cc360e41b81526001600160a01b0384811660048301528581166024830152861515604483015296979660209694959394939290919087908290606490829060101c86165afa9081156127fb5785916127de575b50169384156127d3576004928695949261275092612c55565b959093604051938480926318160ddd60e01b82525afa9384156127c657819461278f575b50505061278c9261107b8361107661107694896126a6565b90565b909180939450813d83116127bf575b6127a88183612348565b81010312610316575051908261107b611076612774565b503d61279e565b50604051903d90823e3d90fd5b505050935050508190565b6127f59150873d8911611172576111638183612348565b38612737565b6040513d87823e3d90fd5b6001600160a01b0392916128199161289d565b90600054926040519060208201926bffffffffffffffffffffffff199485809260601b16855260601b166034830152151560f81b60488201526029815261285f816122ca565b5190206003549060405192602084019460ff60f81b865260501b166021840152603583015260558201526055815261289681612310565b5190201690565b90916001600160a01b03918284168382168181146128f75710156128f257925b918316156128c757565b606460405162461bcd60e51b81526020600482015260046024820152635a45524f60e01b6044820152fd5b6128bd565b60405162461bcd60e51b815260206004820152600960248201527f4944454e544943414c00000000000000000000000000000000000000000000006044820152606490fd5b919091612949828461289d565b939092600093845492604092835192602093848101916bffffffffffffffffffffffff199a8b809260601b16845260601b166034820152600160f81b604882015260298152612997816122ca565b51902090600354918551908582019160ff60f81b83528b8960501b16918260218301526035820152846055820152605581526129d281612310565b6001600160a01b0392839151902016938a9b838c9a60101c169489519663e5e31b1360e01b978881528160048201528a816024818b5afa908115612c2e578f91612c11575b50612b7e575b5090612a2d89959493928961289d565b90918b5191818884019460601b16845260601b1660348201528d604882015260298152612a59816122ca565b519020908951918583019360ff60f81b855260218401526035830152605582015260558152612a8781612310565b5190201692602487518094819382528660048301525afa908115612b74578891612b57575b50612ad0575b505050509050808311600014612aca57505090600190565b92909150565b83516378a051ad60e11b815260048101969096526001600160a01b0391909116602486015291939250908190839060449082905afa928315612b4e57508392612b20575b50508038808080612ab2565b90809250813d8311612b47575b612b378183612348565b810103126103fb57513880612b14565b503d612b2d565b513d85823e3d90fd5b612b6e9150843d86116103ea576103dc8183612348565b38612aac565b85513d8a823e3d90fd5b8a516378a051ad60e11b8152600481018e90526001600160a01b038a166024820152919e508990829060449082905afa9081156115a357908995949392918e91612bd4575b50612a2d909e919293949550612a1d565b8681939495969792503d8311612c0a575b612bef8183612348565b81010312612c065751889493929190612a2d612bc3565b8c80fd5b503d612be5565b612c2891508b3d8d116103ea576103dc8183612348565b38612a17565b8f8d51903d90823e3d90fd5b90816060910312610353578051916040602083015192015190565b600491926060612c65858461289d565b5094612c7b6001600160a01b0393849286612806565b1660405194858092630240bc6b60e21b82525afa938415612ceb57600093600095612cb5575b508116911614600014612cb15791565b9091565b612cdb91955082945060603d606011612ce4575b612cd38183612348565b810190612c3a565b50949093612ca1565b503d612cc9565b6040513d6000823e3d90fd5b15612cfe57565b634e487b7160e01b600052600160045260246000fd5b9190600190612d2760018251101561262e565b8051600181018091116125a857612d4281959493929561236a565b94612d5d604092612d5584519889612348565b80885261236a565b60209690601f190136888301378095612d7582612564565b52836000976001600160a01b03808a5460101c16925b612d9c575b50505050505050909150565b84518a1015612f0b57612dd281612db38c88612587565b5151168b8861200a8587612dc7858d612587565b51015116928a612587565b865163e5e31b1360e01b81529082166004808301829052909b918481602481895afa908115612f0057600091612ee3575b50612e14575b508701995086612d8b565b83612e1f8388612587565b5184612e2b858b612587565b51518b516378a051ad60e11b815285810193845291166001600160a01b031660208301529d8e918290819060400103915afa9b8c15612ed85760009c612ea9575b5088820190818311612e9457509088999a9b612e898a9388612587565b52908b9a9950612e09565b601190634e487b7160e01b6000525260246000fd5b909b8482813d8311612ed1575b612ec08183612348565b810103126103165750519a38612e6c565b503d612eb6565b88513d6000823e3d90fd5b612efa9150853d87116103ea576103dc8183612348565b38612e03565b89513d6000823e3d90fd5b612d90565b3d15612f4b573d9067ffffffffffffffff82116122e65760405191612f3f601f8201601f191660200184612348565b82523d6000602084013e565b606090565b90929192813b15610353576040516323b872dd60e01b602082019081526001600160a01b039283166024830152949091166044820152606481019290925260009283928390612fac81608481015b03601f198101835282612348565b51925af1612fb8612f10565b81612fc6575b501561035357565b8051801592508215612fdb575b505038612fbe565b612fee92506020809183010191016124b4565b3880612fd3565b926001600160a01b039195949295845260209560208501521660408301526080606083015280519081608084015260005b82811061304857505060a09293506000838284010152601f8019910116010190565b81810186015184820160a001528501613026565b9160005b82518110156131cb576001600160a01b038061307c8386612587565b51511661309b6020918383613091878a612587565b510151169061289d565b5060018401928385116125a8576130b28489612587565b519181806130c0888b612587565b5151169116146000146131c357600091935b875160001981019081116125a85788908710156131ba5781604061200a858861310c85836131036131179a8a612587565b51511697612587565b51015116928c612587565b905b6131498180613128898c612587565b51511695613136898c612587565b51015116946040958661200a8a8d612587565b168351946131568661232c565b60008652813b15610353576000809461318487519889968795869463022c0d9f60e01b865260048601612ff5565b03925af19081156131b0575090600192916131a1575b5001613060565b6131aa906122fc565b3861319a565b513d6000823e3d90fd5b50508590613119565b6000936130d2565b50505050565b60008080938193826040516131e58161232c565b525af16131f0612f10565b50156131f857565b60405162461bcd60e51b815260206004820152601360248201527f455448205452414e53464552204641494c4544000000000000000000000000006044820152606490fd5b919095929594939484871061035357838610610353576000546040516306801cc360e41b81526001600160a01b0385811660048301528381166024830152841515604483015260109290921c8216949160209182816064818a5afa908115612ceb57600091613397575b501615613328575b506132ba9350612c55565b9290801580613320575b156132d157505050509091565b6132e084828897959697613666565b948386116132f85750505050612cb190821015612518565b839550612cb194509061330f916133189394613666565b94851115612cf7565b8310156124cc565b5083156132c4565b6040516320b7f73960e21b81526001600160a01b038381166004830152841660248201528415156044820152948190869060649082906000905af1948515612ceb576132ba95613379575b506132af565b8161338f92903d10611172576111638183612348565b503880613373565b6133ae9150833d8511611172576111638183612348565b386132a7565b919091803b156103535760405163a9059cbb60e01b602082019081526001600160a01b039094166024820152604481019290925260009283928390612fac8160648101612f9e565b9060005b81811061340d5750505050565b61342061341b82848661260a565b61261a565b8260206134328161122686858a61260a565b9061343d828561289d565b509361344d61341b87868b61260a565b9261345d8361122689888d61260a565b6134836001600160a01b039586926104a18d61347d8d60409c8d9361260a565b0161267a565b1691855196630240bc6b60e21b88526060600496818a8981895afa998a15612f0057600092839b61363c575b505090818493928896951692168214998a6000146136345750905b8851968780926370a0823160e01b8252888b8301526024998a915afa908115612f0057600091613605575b5061350a9392916135059161259b565b61293c565b5095156135fd57600095925b60001989018981116135e9578810156135e05760018801908189116135cd575090896104a18761347d858d61356161355561341b6135679a848a61260a565b9761122684848a61260a565b9561260a565b945b84516135748161232c565b60008152823b15610353576000946135a186928851998a978896879563022c0d9f60e01b87528601612ff5565b03925af19081156131b0575090600192916135be575b5001613400565b6135c7906122fc565b386135b7565b634e487b7160e01b600090815260118752fd5b50508894613569565b50634e487b7160e01b600090815260118652fd5b600092613516565b908582813d831161362d575b61361b8183612348565b8101031261031657505161350a6134f5565b503d613611565b9050906134ca565b613659929b50889695949350803d10612ce457612cd38183612348565b50999091929394386134af565b80156136d557811515806136cc575b156136875761278c92611076916126a6565b60405162461bcd60e51b815260206004820152601660248201527f494e53554646494349454e54204c4951554944495459000000000000000000006044820152606490fd5b50821515613675565b60405162461bcd60e51b815260206004820152601360248201527f494e53554646494349454e5420414d4f554e54000000000000000000000000006044820152606490fd5b8015613857576137e5816000908360801c8061384b575b508060401c8061383e575b508060201c80613831575b508060101c80613824575b508060081c80613817575b508060041c8061380a575b508060021c806137fd575b50600191828092811c6137f6575b1c1b61378d81856126b9565b01811c61379a81856126b9565b01811c6137a781856126b9565b01811c6137b481856126b9565b01811c6137c181856126b9565b01811c6137ce81856126b9565b01811c6137db81856126b9565b01901c80926126b9565b808210156137f1575090565b905090565b0181613781565b6002915091019038613773565b6004915091019038613768565b600891509101903861375d565b6010915091019038613752565b6020915091019038613747565b604091509101903861373c565b91505060809038613731565b5060009056fea164736f6c6343000816000a
Deployed Bytecode
0x604060808152600480361015610035575b5050361561001d57600080fd5b6100336001600160a01b03600254163314612cf7565b005b600090813560e01c80630dede6c41461204457806313dcfc5914611eb957806318a1308614611d075780633fc8cef314611cdf5780634386e63c14611ca6578063448725b414611bb05780634c1ee03e14611b6f578063544caa5614611b2b5780635a47ddc314611a0c5780635d3590d5146119845780635e1e6325146119475780635e60dab51461191257806367ffb66a146117645780636cc1ae13146116c15780637301e3c81461160e57806376c72751146113955780637af728c8146111e15780639881fcb41461118357806398a0fb3c14610f2d578063a32b1fcd14610cd8578063b7e0d4c014610b01578063c0c53b8b146108b7578063c45a01551461088e578063d33219b414610866578063d7b0e0a514610666578063e2d9d4dc14610583578063e5e31b13146104fa578063f41766d8146103ff5763fe411f14146101815750610010565b346103fb5761018f3661241a565b979395909491969297421115966101a588612468565b6101c66001600160a01b03936101bf85600254169a612468565b8984612806565b8a516323b872dd60e01b8152338682019081526001600160a01b038316602082810191909152604082019a909a529185169189908290819060600103818a865af19081156103f15787916103c4575b50156103af57908a8692602482518095819363226bf2d160e21b8352308b8401525af19889156103ba578692879a61037e575b50610253908461289d565b5083851692908516830361036957916102808992610278602496959d8e5b10156124cc565b8b1015612518565b8b516370a0823160e01b8152308782015293849182905afa90811561035f5786908692610327575b6102b293506133b4565b6002541690813b15610323578560248492838b519586948593632e1a7d4d60e01b85528401525af1801561031957908592916102fe575b50506102f4916131d1565b8351928352820152f35b81925061030a906122fc565b610316578084916102e9565b80fd5b87513d84823e3d90fd5b8280fd5b9150508682813d8311610358575b61033f8183612348565b8101031261035357856102b29251916102a8565b600080fd5b503d610335565b8a513d87823e3d90fd5b98916102808992610278602496959d8e610271565b8c80929b508194503d83116103b3575b6103988183612348565b810103126103af5781519188015198610253610248565b8580fd5b503d61038e565b8b513d88823e3d90fd5b6103e49150893d8b116103ea575b6103dc8183612348565b8101906124b4565b38610215565b503d6103d2565b8c513d89823e3d90fd5b5080fd5b5091346103fb57610439610428610415366121ba565b9893989692959096949194421115612468565b610433368587612382565b90612d14565b95865160001981019081116104e7579061045661045e9289612587565b5110156125be565b81156104d4576104d086866104c6876104c088886104b961047e8361261a565b6104a761048a8561261a565b6104966020870161261a565b6104a18b880161267a565b91612806565b6104b08a612564565b51913390612f50565b3691612382565b8461305c565b519182918261214d565b0390f35b634e487b7160e01b815260328752602490fd5b634e487b7160e01b835260118952602483fd5b5082346103235760203660031901126103235760206105176120d2565b60246001600160a01b039182875460101c168551968794859363e5e31b1360e01b855216908301525afa918215610579576020939261055a575b50519015158152f35b610572919250833d85116103ea576103dc8183612348565b9083610551565b81513d85823e3d90fd5b50346103fb5761059236612209565b9593926001600160a01b039c989a95999b979c966105b58d896002541689612806565b911561065e5787600019925b1692833b1561065a578f5163d505accf60e01b815233818c0190815230602082015260408101949094526060840187905260ff909516608084015260a083015260c08201528891839182908490829060e00103925af180156103f157908791610646575b50506101c690421115986106388a612468565b6101bf85600254169a612468565b61064f906122fc565b6103af578538610625565b8a80fd5b878c926105c1565b50829034610323576106773661241a565b989492969398959190954211159861068e8a612468565b6106f060206106b46001600160a01b03966106ad88600254169e612468565b8d87612806565b8b516323b872dd60e01b8152338982019081526001600160a01b0383166020820152604081019590955290871693909283918291606090910190565b03818a865af190811561085c57879161083d575b50156103af57888691602482518094819363226bf2d160e21b8352308b8401525af1998a15610833578691879b6107f9575b509261076d999a9288928661074e61077a978561289d565b5016878416146000146107ea5790610775919b8c959b5b8610156124cc565b8a1015612518565b6133b4565b6002541690813b15610323578460248492838a519586948593632e1a7d4d60e01b85528401525af180156107e057908492916107c8575b50506107bc916131d1565b82519182526020820152f35b8192506107d4906122fc565b610316578083916107b1565b86513d84823e3d90fd5b9390610775919b8c959b610765565b8a80929c508193503d831161082c575b6108138183612348565b810103126103af5780516020909101519961077a610736565b503d610809565b89513d88823e3d90fd5b610856915060203d6020116103ea576103dc8183612348565b8b610704565b8a513d89823e3d90fd5b8284346103fb57816003193601126103fb576020906001600160a01b03600154169051908152f35b8284346103fb57816003193601126103fb576001600160a01b036020925460101c169051908152f35b508234610323576060366003190112610323576108d26120d2565b906108db6120e8565b6108e3612114565b9085549160ff8360081c161592838094610af4575b8015610add575b15610a745760ff198116600117885583610a63575b506001600160a01b039081602089549775ffffffffffffffffffffffffffffffffffffffff00008160101b16998a7fffffffffffffffffffff0000000000000000000000000000000000000000ffff8b16178c55885180948193631355724960e31b8352165afa908115610a59578991610a23575b50600355817fffffffffffffffffffffffff00000000000000000000000000000000000000009316836002541617600255169060015416176001556109cc578380f35b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498927fffffffffffffffffffff000000000000000000000000000000000000000000ff602093161784555160018152a18180808380f35b90506020813d602011610a51575b81610a3e60209383612348565b81010312610a4d575189610989565b8880fd5b3d9150610a31565b86513d8b823e3d90fd5b61ffff191661010117875587610914565b845162461bcd60e51b8152602081890152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608490fd5b50303b1580156108ff5750600160ff8216146108ff565b50600160ff8216106108f8565b50610b5c91610b5393610b45610b2d610b193661241a565b9b949b979396909597929192421115612468565b6001600160a01b03958660025416908c34928a61323d565b998199856002541687612806565b80953390612f50565b8160025416803b156103af5785899188875180948193630d0e30db60e41b83525af18015610cce57908691610cb6575b50600254855163a9059cbb60e01b81526001600160a01b03861689820190815260208082018d905296939192879284928390036040019183919089165af1908115610cac5784602493610beb889796948b948591610c8f575b50612cf7565b88519a8b9687956335313c2160e11b87521690850152165af1928315610c845792610c52575b506104d09250843411610c3a575b51938493846040919493926060820195825260208201520152565b610c4d610c47863461259b565b336131d1565b610c1f565b90915082813d8311610c7d575b610c698183612348565b81010312610353576104d091519038610c11565b503d610c5f565b8251903d90823e3d90fd5b610ca69150893d8b116103ea576103dc8183612348565b38610be5565b86513d89823e3d90fd5b610cbf906122fc565b610cca578438610b8c565b8480fd5b85513d88823e3d90fd5b50346103fb576101803660031901126103fb57610cf36120d2565b610cfb6120e8565b92610d0461213e565b90606435610d106120fe565b9060e4359361010435948515158603610353576101243560ff8116810361035357610d3c838b8a612806565b9615610f2657600019905b6001600160a01b0380981690813b15610f22578c5163d505accf60e01b815233818d0190815230602082015260408101949094526060840185905260ff90911660808401526101443560a08401526101643560c0840152918791839182908490829060e00103925af180156103ba57908691610f0e575b5050610ddc610e1892610dd5602093421115612468565b8a89612806565b8a516323b872dd60e01b8152338a82019081526001600160a01b0383166020820152604081019590955290871693909283918291606090910190565b038187865af1908115610f04578491610ee5575b501561032357602488928486938551998a95869463226bf2d160e21b865216908401525af1948515610ed95781948296610e9f575b5090610e6e83928561289d565b50905016911614600014610e9a57905b610e8c6084358310156124cc565b6107bc60a435821015612518565b610e7e565b87809297508196503d8311610ed2575b610eb98183612348565b8101031261031657835160209094015194610e6e610e61565b503d610eaf565b508551903d90823e3d90fd5b610efe915060203d6020116103ea576103dc8183612348565b38610e2c565b89513d86823e3d90fd5b610f17906122fc565b610cca578438610dbe565b8780fd5b8390610d47565b509190346103165760a036600319011261031657610f496120d2565b91610f526120e8565b91610f5b61213e565b936064359360843595826001600160a01b039182865460101c16938a885180966306801cc360e41b82528180610fb8878760209d8e98850191939260409160608401956001600160a01b0380921685521660208401521515910152565b03915afa94851561117957908b9291889661114a575b5087968895899716806110cb575b5050505050508215806110c3575b1561104157505050611004610fff85856126a6565b61371a565b6103e71981019190821161102e575090519182526020820192909252604081019190915260609150f35b634e487b7160e01b815260118652602490fd5b909592919650611052818887613666565b9280841161109a5750611081906110766104d0969761107b869a611076838c6126a6565b6126b9565b956126a6565b90508082101561109357505b90610c1f565b905061108d565b92506104d09450806110766110b3896110819487613666565b9761107b869a611076838c6126a6565b508015610fea565b91949750929550829194508851958680926318160ddd60e01b82525afa908115611140578691611110575b50611102935093612c55565b919091388881808080610fdc565b905083813d8311611139575b6111268183612348565b81010312610353576111029251386110f6565b503d61111c565b87513d88823e3d90fd5b61116b919650873d8911611172575b6111638183612348565b810190612687565b9438610fce565b503d611159565b88513d89823e3d90fd5b509190346103165781600319360112610316576024359067ffffffffffffffff8211610316573660238301121561031657506104d0926111cf6111d69236906024818501359101612382565b9035612d14565b90519182918261214d565b5091346103fb576112026111f4366121ba565b969493959096421115612468565b6000198101818111611382579061122c61122696959493926020978891848661260a565b0161261a565b926112476001600160a01b039485806002541691161461262e565b811561136f5782899695949261128f611296936112648e9761261a565b6112878c61127c6112748861261a565b91880161261a565b6104a18c890161267a565b903390612f50565b30916133fc565b600254169282516370a0823160e01b815230838201528681602481885afa96871561136557869761132f575b50506112d0908610156125be565b823b1561132b5784602485928385519687948593632e1a7d4d60e01b85528401525af1908115611322575061130e575b505061130b916131d1565b80f35b611317906122fc565b610323578284611300565b513d84823e3d90fd5b8380fd5b809297508196503d831161135e575b6113488183612348565b81010312610353576112d08794519590896112c2565b503d61133e565b84513d88823e3d90fd5b634e487b7160e01b895260328a52602489fd5b634e487b7160e01b885260118952602488fd5b506113b3836113a33661227e565b9692969590919395421115612468565b82156115fb57906113e191876113c88861261a565b6002546001600160a01b0395908616918616821461262e565b803b156103fb57818491885192838092630d0e30db60e41b825234905af18015610319576115e7575b509261143e9381600254166114716114218b61261a565b9160209788938d6104a18d61143788840161261a565b920161267a565b8a5163a9059cbb60e01b81526001600160a01b039091168882019081523460208201529094859384928391604090910190565b03925af19081156115dd579061148d918b916115c05750612cf7565b60001985018581116115ad57816114a986611226848a8e61260a565b16958751996370a0823160e01b94858c52878c6024818885169c8d8c8301525afa9b8c156115a3578d9c611566575b506112268897969484846114f48b9560249a986114f9986133fc565b61260a565b168751968794859384528301525afa92831561155d5750859261152d575b505061130b926115269161259b565b10156125be565b90809250813d8311611556575b6115448183612348565b81010312610353575182611526611517565b503d61153a565b513d87823e3d90fd5b909695939b508781819694963d831161159c575b6115848183612348565b8101031261035357519a9495929491939192876114d8565b503d61157a565b8a513d8f823e3d90fd5b634e487b7160e01b8a526011845260248afd5b6115d79150863d88116103ea576103dc8183612348565b8b610be5565b87513d8c823e3d90fd5b6115f0906122fc565b610f2257878961140a565b634e487b7160e01b875260328252602487fd5b5091346103fb5760803660031901126103fb5782359167ffffffffffffffff8084116103fb57366023850112156103fb578385013561164c8161236a565b9461165985519687612348565b8186526020916024602088019160051b830101913683116103af57602401905b8282106116b257505050506024359081116103fb5761169b9036908601612189565b6116a3612114565b9261045e426064351015612468565b81358152908301908301611679565b508234610323576116e6906116d5366121ba565b979297969091949396421115612468565b8315611751576117196116f88861261a565b936117028961261a565b946112876020968b6104a18b6114378b840161261a565b600019840184811161173e576001600160a01b0390816114a986611226848a8e61260a565b634e487b7160e01b895260118352602489fd5b634e487b7160e01b885260328252602488fd5b50826117826117723661227e565b9691929396949094421115612468565b81156118ff576117ad6117948461261a565b6002546001600160a01b0392908316918316821461262e565b6117c16117bb368688612382565b34612d14565b97885160001981019081116118ec578a92916104566117e0928c612587565b6117e989612564565b5190803b15610323578290858a5180948193630d0e30db60e41b83525af180156118e2576118ce575b505061187d916020916002541661184161182b8761261a565b61183685890161261a565b6104a18b8a0161267a565b8a61184b8b612564565b518a5163a9059cbb60e01b81526001600160a01b03909316948301948552602085015290948593849291839160400190565b03925af19081156118c457916104b96104c69594926104c0946104d09a916118a55750612cf7565b6118be915060203d6020116103ea576103dc8183612348565b8a610be5565b85513d89823e3d90fd5b6118d7906122fc565b610f22578789611812565b88513d84823e3d90fd5b634e487b7160e01b8b526011855260248bfd5b634e487b7160e01b875260329052602486fd5b50503461031657606036600319011261031657506107bc6119316120d2565b6119396120e8565b61194161213e565b91612c55565b5090346103165760603660031901126103165750611976906119676120e8565b61196f612114565b913561293c565b825191825215156020820152f35b50346103fb5760603660031901126103fb5761199e6120d2565b906119a76120e8565b906001600160a01b036001541633036119c957509061130b91604435916133b4565b606490602086519162461bcd60e51b8352820152600660248201527f2141444d494e00000000000000000000000000000000000000000000000000006044820152fd5b509190346103165761012036600319011261031657611a296120d2565b90611a326120e8565b92611a3b61213e565b9260e4356001600160a01b0380821680920361035357611aa59785602492611aac611a9a602097611a8c8c8e611a7642610104351015612468565b60c4359160a4359160843591606435918761323d565b9e8f93829f929e8385612806565b9d8e80943390612f50565b3390612f50565b865198899586946335313c2160e11b8652850152165af1918215611b205791611aea575b519283526020830193909352506040810191909152606090f35b90506020823d602011611b18575b81611b0560209383612348565b81010312610353576104d0915190611ad0565b3d9150611af8565b9051903d90823e3d90fd5b50503461031657816003193601126103165750611b57611b496120d2565b611b516120e8565b9061289d565b82516001600160a01b03928316815291166020820152f35b8284346103fb5760603660031901126103fb576020906001600160a01b03611ba8611b986120d2565b611ba06120e8565b6104a161213e565b915191168152f35b5082903461032357611bc136612209565b92899d99979b989493611be56001600160a01b039c98979c998a600254168a612806565b9115611c9e5788600019925b1692833b15611c9a578e5163d505accf60e01b815233818d0190815230602082015260408101949094526060840187905260ff909516608084015260a083015260c08201528991839182908490829060e00103925af18015611c9057611c78575b5060206106b4611c6a9c6106f0934211159d8e612468565b6106ad88600254169e612468565b611c8288916122fc565b611c8c578b611c52565b8680fd5b8b513d8a823e3d90fd5b8b80fd5b888692611bf1565b50503461031657608036600319011261031657506107bc611cc56120d2565b611ccd6120e8565b611cd561213e565b90606435926126d9565b8284346103fb57816003193601126103fb576020906001600160a01b03600254169051908152f35b5091346103fb57611d2b611d1a366121ba565b979397959095949294421115612468565b60001993818501828111611ea657611d4c6020611226611d7293868661260a565b93611d676001600160a01b039586806002541691161461262e565b610433368585612382565b978851868101908111611e935790610456611d8d928b612587565b8115611e805790611ddd82611dd4611da7611de39561261a565b611dcb611db38461261a565b8c6104a1611dc36020880161261a565b91870161267a565b6104b08d612564565b30923691612382565b8861305c565b600254168551838101908111611e6d57611dfd9087612587565b51813b156103235782916024839288519485938492632e1a7d4d60e01b84528d8401525af18015611e6357611e54575b50845191820191821161102e576104d085856104c686611e4d8785612587565b51906131d1565b611e5d906122fc565b38611e2d565b85513d84823e3d90fd5b634e487b7160e01b835260118852602483fd5b634e487b7160e01b845260328952602484fd5b634e487b7160e01b865260118b52602486fd5b634e487b7160e01b855260118a52602485fd5b5082346103235760e036600319011261032357611ed4612114565b606435926001600160a01b03908185168095036103af5760843591821515809303611c8c5760a435908082168203610f2257611f144260c4351015612468565b85519386850185811067ffffffffffffffff82111761203157875260018552885b602080821015611f6657885160209291611f4e826122ca565b8c82528c818301528c8b830152828901015201611f35565b50509194979690929783611f7986612564565b51911690526020611f8985612564565b51015284611f9684612564565b510152611fa4828735612d14565b80519095600019820191821161201e576104d087876104c688886104c089611fd26024356104568c8a612587565b61201581611fdf85612564565b5151169180611fed86612564565b515116906020611ffc87612564565b510151168861200a87612564565b510151151591612806565b6104b088612564565b634e487b7160e01b815260118852602490fd5b634e487b7160e01b8a526041855260248afd5b50346103fb576101003660031901126103fb5761205f6120d2565b6120676120e8565b9261207061213e565b9061209261207c6120fe565b9261208b4260e4351015612468565b8685612806565b86516323b872dd60e01b8152338682019081526001600160a01b039283166020828101829052606435604084015293959390929182908190606001610e18565b600435906001600160a01b038216820361035357565b602435906001600160a01b038216820361035357565b60c435906001600160a01b038216820361035357565b604435906001600160a01b038216820361035357565b35906001600160a01b038216820361035357565b60443590811515820361035357565b602090602060408183019282815285518094520193019160005b828110612175575050505090565b835185529381019392810192600101612167565b9181601f840112156103535782359167ffffffffffffffff8311610353576020808501946060850201011161035357565b60a06003198201126103535760043591602435916044359067ffffffffffffffff8211610353576121ed91600401612189565b90916064356001600160a01b0381168103610353579060843590565b610160906003190112610353576001600160a01b0390600435828116810361035357916024358015158103610353579160443591606435916084359160a4359081168103610353579060c4359060e435801515810361035357906101043560ff81168103610353579061012435906101443590565b90608060031983011261035357600435916024359067ffffffffffffffff8211610353576122ae91600401612189565b90916044356001600160a01b0381168103610353579060643590565b6060810190811067ffffffffffffffff8211176122e657604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116122e657604052565b6080810190811067ffffffffffffffff8211176122e657604052565b6020810190811067ffffffffffffffff8211176122e657604052565b90601f8019910116810190811067ffffffffffffffff8211176122e657604052565b67ffffffffffffffff81116122e65760051b60200190565b92919261238e8261236a565b60409461239e6040519283612348565b8195848352602080930191606080960285019481861161035357925b8584106123ca5750505050505050565b8684830312610353578251906123df826122ca565b6123e88561212a565b82526123f586860161212a565b868301528385013590811515820361035357828792868b9501528152019301926123ba565b60e0906003190112610353576001600160a01b0390600435828116810361035357916024358015158103610353579160443591606435916084359160a4359081168103610353579060c43590565b1561246f57565b60405162461bcd60e51b815260206004820152600760248201527f45585049524544000000000000000000000000000000000000000000000000006044820152606490fd5b90816020910312610353575180151581036103535790565b156124d357565b60405162461bcd60e51b815260206004820152600e60248201527f494e53554646494349454e5420410000000000000000000000000000000000006044820152606490fd5b1561251f57565b60405162461bcd60e51b815260206004820152600e60248201527f494e53554646494349454e5420420000000000000000000000000000000000006044820152606490fd5b8051156125715760200190565b634e487b7160e01b600052603260045260246000fd5b80518210156125715760209160051b010190565b919082039182116125a857565b634e487b7160e01b600052601160045260246000fd5b156125c557565b60405162461bcd60e51b815260206004820152601360248201527f494e53554646494349454e54204f5554505554000000000000000000000000006044820152606490fd5b9190811015612571576060020190565b356001600160a01b03811681036103535790565b1561263557565b60405162461bcd60e51b815260206004820152600c60248201527f494e56414c4944205041544800000000000000000000000000000000000000006044820152606490fd5b3580151581036103535790565b9081602091031261035357516001600160a01b03811681036103535790565b818102929181159184041417156125a857565b81156126c3570490565b634e487b7160e01b600052601260045260246000fd5b600080546040516306801cc360e41b81526001600160a01b0384811660048301528581166024830152861515604483015296979660209694959394939290919087908290606490829060101c86165afa9081156127fb5785916127de575b50169384156127d3576004928695949261275092612c55565b959093604051938480926318160ddd60e01b82525afa9384156127c657819461278f575b50505061278c9261107b8361107661107694896126a6565b90565b909180939450813d83116127bf575b6127a88183612348565b81010312610316575051908261107b611076612774565b503d61279e565b50604051903d90823e3d90fd5b505050935050508190565b6127f59150873d8911611172576111638183612348565b38612737565b6040513d87823e3d90fd5b6001600160a01b0392916128199161289d565b90600054926040519060208201926bffffffffffffffffffffffff199485809260601b16855260601b166034830152151560f81b60488201526029815261285f816122ca565b5190206003549060405192602084019460ff60f81b865260501b166021840152603583015260558201526055815261289681612310565b5190201690565b90916001600160a01b03918284168382168181146128f75710156128f257925b918316156128c757565b606460405162461bcd60e51b81526020600482015260046024820152635a45524f60e01b6044820152fd5b6128bd565b60405162461bcd60e51b815260206004820152600960248201527f4944454e544943414c00000000000000000000000000000000000000000000006044820152606490fd5b919091612949828461289d565b939092600093845492604092835192602093848101916bffffffffffffffffffffffff199a8b809260601b16845260601b166034820152600160f81b604882015260298152612997816122ca565b51902090600354918551908582019160ff60f81b83528b8960501b16918260218301526035820152846055820152605581526129d281612310565b6001600160a01b0392839151902016938a9b838c9a60101c169489519663e5e31b1360e01b978881528160048201528a816024818b5afa908115612c2e578f91612c11575b50612b7e575b5090612a2d89959493928961289d565b90918b5191818884019460601b16845260601b1660348201528d604882015260298152612a59816122ca565b519020908951918583019360ff60f81b855260218401526035830152605582015260558152612a8781612310565b5190201692602487518094819382528660048301525afa908115612b74578891612b57575b50612ad0575b505050509050808311600014612aca57505090600190565b92909150565b83516378a051ad60e11b815260048101969096526001600160a01b0391909116602486015291939250908190839060449082905afa928315612b4e57508392612b20575b50508038808080612ab2565b90809250813d8311612b47575b612b378183612348565b810103126103fb57513880612b14565b503d612b2d565b513d85823e3d90fd5b612b6e9150843d86116103ea576103dc8183612348565b38612aac565b85513d8a823e3d90fd5b8a516378a051ad60e11b8152600481018e90526001600160a01b038a166024820152919e508990829060449082905afa9081156115a357908995949392918e91612bd4575b50612a2d909e919293949550612a1d565b8681939495969792503d8311612c0a575b612bef8183612348565b81010312612c065751889493929190612a2d612bc3565b8c80fd5b503d612be5565b612c2891508b3d8d116103ea576103dc8183612348565b38612a17565b8f8d51903d90823e3d90fd5b90816060910312610353578051916040602083015192015190565b600491926060612c65858461289d565b5094612c7b6001600160a01b0393849286612806565b1660405194858092630240bc6b60e21b82525afa938415612ceb57600093600095612cb5575b508116911614600014612cb15791565b9091565b612cdb91955082945060603d606011612ce4575b612cd38183612348565b810190612c3a565b50949093612ca1565b503d612cc9565b6040513d6000823e3d90fd5b15612cfe57565b634e487b7160e01b600052600160045260246000fd5b9190600190612d2760018251101561262e565b8051600181018091116125a857612d4281959493929561236a565b94612d5d604092612d5584519889612348565b80885261236a565b60209690601f190136888301378095612d7582612564565b52836000976001600160a01b03808a5460101c16925b612d9c575b50505050505050909150565b84518a1015612f0b57612dd281612db38c88612587565b5151168b8861200a8587612dc7858d612587565b51015116928a612587565b865163e5e31b1360e01b81529082166004808301829052909b918481602481895afa908115612f0057600091612ee3575b50612e14575b508701995086612d8b565b83612e1f8388612587565b5184612e2b858b612587565b51518b516378a051ad60e11b815285810193845291166001600160a01b031660208301529d8e918290819060400103915afa9b8c15612ed85760009c612ea9575b5088820190818311612e9457509088999a9b612e898a9388612587565b52908b9a9950612e09565b601190634e487b7160e01b6000525260246000fd5b909b8482813d8311612ed1575b612ec08183612348565b810103126103165750519a38612e6c565b503d612eb6565b88513d6000823e3d90fd5b612efa9150853d87116103ea576103dc8183612348565b38612e03565b89513d6000823e3d90fd5b612d90565b3d15612f4b573d9067ffffffffffffffff82116122e65760405191612f3f601f8201601f191660200184612348565b82523d6000602084013e565b606090565b90929192813b15610353576040516323b872dd60e01b602082019081526001600160a01b039283166024830152949091166044820152606481019290925260009283928390612fac81608481015b03601f198101835282612348565b51925af1612fb8612f10565b81612fc6575b501561035357565b8051801592508215612fdb575b505038612fbe565b612fee92506020809183010191016124b4565b3880612fd3565b926001600160a01b039195949295845260209560208501521660408301526080606083015280519081608084015260005b82811061304857505060a09293506000838284010152601f8019910116010190565b81810186015184820160a001528501613026565b9160005b82518110156131cb576001600160a01b038061307c8386612587565b51511661309b6020918383613091878a612587565b510151169061289d565b5060018401928385116125a8576130b28489612587565b519181806130c0888b612587565b5151169116146000146131c357600091935b875160001981019081116125a85788908710156131ba5781604061200a858861310c85836131036131179a8a612587565b51511697612587565b51015116928c612587565b905b6131498180613128898c612587565b51511695613136898c612587565b51015116946040958661200a8a8d612587565b168351946131568661232c565b60008652813b15610353576000809461318487519889968795869463022c0d9f60e01b865260048601612ff5565b03925af19081156131b0575090600192916131a1575b5001613060565b6131aa906122fc565b3861319a565b513d6000823e3d90fd5b50508590613119565b6000936130d2565b50505050565b60008080938193826040516131e58161232c565b525af16131f0612f10565b50156131f857565b60405162461bcd60e51b815260206004820152601360248201527f455448205452414e53464552204641494c4544000000000000000000000000006044820152606490fd5b919095929594939484871061035357838610610353576000546040516306801cc360e41b81526001600160a01b0385811660048301528381166024830152841515604483015260109290921c8216949160209182816064818a5afa908115612ceb57600091613397575b501615613328575b506132ba9350612c55565b9290801580613320575b156132d157505050509091565b6132e084828897959697613666565b948386116132f85750505050612cb190821015612518565b839550612cb194509061330f916133189394613666565b94851115612cf7565b8310156124cc565b5083156132c4565b6040516320b7f73960e21b81526001600160a01b038381166004830152841660248201528415156044820152948190869060649082906000905af1948515612ceb576132ba95613379575b506132af565b8161338f92903d10611172576111638183612348565b503880613373565b6133ae9150833d8511611172576111638183612348565b386132a7565b919091803b156103535760405163a9059cbb60e01b602082019081526001600160a01b039094166024820152604481019290925260009283928390612fac8160648101612f9e565b9060005b81811061340d5750505050565b61342061341b82848661260a565b61261a565b8260206134328161122686858a61260a565b9061343d828561289d565b509361344d61341b87868b61260a565b9261345d8361122689888d61260a565b6134836001600160a01b039586926104a18d61347d8d60409c8d9361260a565b0161267a565b1691855196630240bc6b60e21b88526060600496818a8981895afa998a15612f0057600092839b61363c575b505090818493928896951692168214998a6000146136345750905b8851968780926370a0823160e01b8252888b8301526024998a915afa908115612f0057600091613605575b5061350a9392916135059161259b565b61293c565b5095156135fd57600095925b60001989018981116135e9578810156135e05760018801908189116135cd575090896104a18761347d858d61356161355561341b6135679a848a61260a565b9761122684848a61260a565b9561260a565b945b84516135748161232c565b60008152823b15610353576000946135a186928851998a978896879563022c0d9f60e01b87528601612ff5565b03925af19081156131b0575090600192916135be575b5001613400565b6135c7906122fc565b386135b7565b634e487b7160e01b600090815260118752fd5b50508894613569565b50634e487b7160e01b600090815260118652fd5b600092613516565b908582813d831161362d575b61361b8183612348565b8101031261031657505161350a6134f5565b503d613611565b9050906134ca565b613659929b50889695949350803d10612ce457612cd38183612348565b50999091929394386134af565b80156136d557811515806136cc575b156136875761278c92611076916126a6565b60405162461bcd60e51b815260206004820152601660248201527f494e53554646494349454e54204c4951554944495459000000000000000000006044820152606490fd5b50821515613675565b60405162461bcd60e51b815260206004820152601360248201527f494e53554646494349454e5420414d4f554e54000000000000000000000000006044820152606490fd5b8015613857576137e5816000908360801c8061384b575b508060401c8061383e575b508060201c80613831575b508060101c80613824575b508060081c80613817575b508060041c8061380a575b508060021c806137fd575b50600191828092811c6137f6575b1c1b61378d81856126b9565b01811c61379a81856126b9565b01811c6137a781856126b9565b01811c6137b481856126b9565b01811c6137c181856126b9565b01811c6137ce81856126b9565b01811c6137db81856126b9565b01901c80926126b9565b808210156137f1575090565b905090565b0181613781565b6002915091019038613773565b6004915091019038613768565b600891509101903861375d565b6010915091019038613752565b6020915091019038613747565b604091509101903861373c565b91505060809038613731565b5060009056fea164736f6c6343000816000a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.