Source Code
Latest 25 from a total of 104 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Remove Liquidity | 24498320 | 156 days ago | IN | 0 FRAX | 0.00002988 | ||||
| Remove Liquidity | 21766340 | 219 days ago | IN | 0 FRAX | 0.00027391 | ||||
| Swap Exact ETH F... | 18568201 | 293 days ago | IN | 0.00004839 FRAX | 0.00000033 | ||||
| Swap Exact ETH F... | 18547965 | 293 days ago | IN | 0.0000129 FRAX | 0.00000032 | ||||
| Swap Exact ETH F... | 17280857 | 323 days ago | IN | 0.00003 FRAX | 0.00000035 | ||||
| Remove Liquidity | 12385542 | 436 days ago | IN | 0 FRAX | 0.0000047 | ||||
| Swap Exact ETH F... | 11693377 | 452 days ago | IN | 0.00001 FRAX | 0.00000149 | ||||
| Swap Exact ETH F... | 9743279 | 497 days ago | IN | 0.0001 FRAX | 0.00000044 | ||||
| Swap Exact ETH F... | 9729693 | 497 days ago | IN | 0.0001 FRAX | 0.00000061 | ||||
| Swap Exact ETH F... | 9645317 | 499 days ago | IN | 0.0001 FRAX | 0.00000054 | ||||
| Swap Exact Token... | 9603616 | 500 days ago | IN | 0 FRAX | 0.00000067 | ||||
| Swap Exact ETH F... | 9601441 | 500 days ago | IN | 0.0001 FRAX | 0.00000064 | ||||
| Swap Exact ETH F... | 9596724 | 500 days ago | IN | 0.0001 FRAX | 0.00000261 | ||||
| Remove Liquidity | 9561487 | 501 days ago | IN | 0 FRAX | 0.000001 | ||||
| Add Liquidity ET... | 9518755 | 502 days ago | IN | 0.00008 FRAX | 0.00000451 | ||||
| Swap Exact ETH F... | 9515072 | 502 days ago | IN | 0.0001 FRAX | 0.00000038 | ||||
| Swap Exact Token... | 9495546 | 503 days ago | IN | 0 FRAX | 0.00000018 | ||||
| Remove Liquidity | 9495495 | 503 days ago | IN | 0 FRAX | 0.0000002 | ||||
| Swap Exact ETH F... | 9485614 | 503 days ago | IN | 0.00008 FRAX | 0.00000042 | ||||
| Swap Exact ETH F... | 9473555 | 503 days ago | IN | 0.0001 FRAX | 0.0000004 | ||||
| Swap Exact ETH F... | 9455115 | 504 days ago | IN | 0.0001 FRAX | 0.00000052 | ||||
| Swap Exact ETH F... | 9438352 | 504 days ago | IN | 0.000001 FRAX | 0.00000035 | ||||
| Swap Exact ETH F... | 9438343 | 504 days ago | IN | 0.000001 FRAX | 0.00000043 | ||||
| Swap Exact Token... | 9431210 | 504 days ago | IN | 0 FRAX | 0.00000049 | ||||
| Swap Exact ETH F... | 9428836 | 504 days ago | IN | 0.0001 FRAX | 0.00000041 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 18568201 | 293 days ago | 0.00004839 FRAX | ||||
| 18547965 | 293 days ago | 0.0000129 FRAX | ||||
| 17280857 | 323 days ago | 0.00003 FRAX | ||||
| 11693377 | 452 days ago | 0.00001 FRAX | ||||
| 9743279 | 497 days ago | 0.0001 FRAX | ||||
| 9729693 | 497 days ago | 0.0001 FRAX | ||||
| 9645317 | 499 days ago | 0.0001 FRAX | ||||
| 9603616 | 500 days ago | 0.00010467 FRAX | ||||
| 9603616 | 500 days ago | 0.00010467 FRAX | ||||
| 9601441 | 500 days ago | 0.0001 FRAX | ||||
| 9596724 | 500 days ago | 0.0001 FRAX | ||||
| 9518755 | 502 days ago | 0.00008 FRAX | ||||
| 9515072 | 502 days ago | 0.0001 FRAX | ||||
| 9495546 | 503 days ago | 0.00713673 FRAX | ||||
| 9495546 | 503 days ago | 0.00713673 FRAX | ||||
| 9485614 | 503 days ago | 0.00008 FRAX | ||||
| 9473555 | 503 days ago | 0.0001 FRAX | ||||
| 9455115 | 504 days ago | 0.0001 FRAX | ||||
| 9438352 | 504 days ago | 0.000001 FRAX | ||||
| 9438343 | 504 days ago | 0.000001 FRAX | ||||
| 9431210 | 504 days ago | 0.00010118 FRAX | ||||
| 9431210 | 504 days ago | 0.00010118 FRAX | ||||
| 9428836 | 504 days ago | 0.0001 FRAX | ||||
| 9427936 | 504 days ago | 0.0001 FRAX | ||||
| 9408698 | 505 days ago | 0.00001693 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Router
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 10000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import {IPairFactory} from "./interfaces/IPairFactory.sol";
import {IPair} from "./interfaces/IPair.sol";
import {IWETH} from "./interfaces/IWETH.sol";
contract Router {
using SafeMath for uint;
struct route {
address from;
address to;
bool stable;
}
address public immutable factory;
IWETH public immutable weth;
uint internal constant MINIMUM_LIQUIDITY = 10**3;
bytes32 immutable pairCodeHash;
modifier ensure(uint deadline) {
require(deadline >= block.timestamp, 'Router: EXPIRED');
_;
}
constructor(address _factory, address _weth) {
factory = _factory;
pairCodeHash = IPairFactory(_factory).pairCodeHash();
weth = IWETH(_weth);
}
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, 'Router: IDENTICAL_ADDRESSES');
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'Router: ZERO_ADDRESS');
}
// 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(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
require(amountA > 0, 'Router: INSUFFICIENT_AMOUNT');
require(reserveA > 0 && reserveB > 0, 'Router: 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 (uint reserveA, uint reserveB) {
(address token0,) = sortTokens(tokenA, tokenB);
(uint reserve0, uint 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(uint amountIn, address tokenIn, address tokenOut) external view returns (uint amount, bool stable) {
address pair = pairFor(tokenIn, tokenOut, true);
uint amountStable;
uint 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(uint amountIn, route[] memory routes) public view returns (uint[] memory amounts) {
require(routes.length >= 1, 'Router: INVALID_PATH');
amounts = new uint[](routes.length+1);
amounts[0] = amountIn;
for (uint 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,
uint amountADesired,
uint amountBDesired
) external view returns (uint amountA, uint amountB, uint liquidity) {
// create the pair if it doesn't exist yet
address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable);
(uint reserveA, uint reserveB) = (0,0);
uint _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 {
uint amountBOptimal = quoteLiquidity(amountADesired, reserveA, reserveB);
if (amountBOptimal <= amountBDesired) {
(amountA, amountB) = (amountADesired, amountBOptimal);
liquidity = Math.min(amountA * _totalSupply / reserveA, amountB * _totalSupply / reserveB);
} else {
uint 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,
uint liquidity
) external view returns (uint amountA, uint 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);
}
(uint reserveA, uint reserveB) = getReserves(tokenA, tokenB, stable);
uint _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,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin
) internal returns (uint amountA, uint 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);
}
(uint reserveA, uint reserveB) = getReserves(tokenA, tokenB, stable);
if (reserveA == 0 && reserveB == 0) {
(amountA, amountB) = (amountADesired, amountBDesired);
} else {
uint amountBOptimal = quoteLiquidity(amountADesired, reserveA, reserveB);
if (amountBOptimal <= amountBDesired) {
require(amountBOptimal >= amountBMin, 'Router: INSUFFICIENT_B_AMOUNT');
(amountA, amountB) = (amountADesired, amountBOptimal);
} else {
uint amountAOptimal = quoteLiquidity(amountBDesired, reserveB, reserveA);
assert(amountAOptimal <= amountADesired);
require(amountAOptimal >= amountAMin, 'Router: INSUFFICIENT_A_AMOUNT');
(amountA, amountB) = (amountAOptimal, amountBDesired);
}
}
}
function addLiquidity(
address tokenA,
address tokenB,
bool stable,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external ensure(deadline) returns (uint amountA, uint amountB, uint 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,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable ensure(deadline) returns (uint amountToken, uint amountETH, uint 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,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) public ensure(deadline) returns (uint amountA, uint amountB) {
address pair = pairFor(tokenA, tokenB, stable);
require(IPair(pair).transferFrom(msg.sender, pair, liquidity)); // send liquidity to pair
(uint amount0, uint amount1) = IPair(pair).burn(to);
(address token0,) = sortTokens(tokenA, tokenB);
(amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
require(amountA >= amountAMin, 'Router: INSUFFICIENT_A_AMOUNT');
require(amountB >= amountBMin, 'Router: INSUFFICIENT_B_AMOUNT');
}
function removeLiquidityETH(
address token,
bool stable,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) public ensure(deadline) returns (uint amountToken, uint 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,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB) {
address pair = pairFor(tokenA, tokenB, stable);
{
uint value = approveMax ? type(uint).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,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH) {
address pair = pairFor(token, address(weth), stable);
uint value = approveMax ? type(uint).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(uint[] memory amounts, route[] memory routes, address _to) internal virtual {
for (uint i = 0; i < routes.length; i++) {
(address token0,) = sortTokens(routes[i].from, routes[i].to);
uint amountOut = amounts[i + 1];
(uint amount0Out, uint amount1Out) = routes[i].from == token0 ? (uint(0), amountOut) : (amountOut, uint(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(
uint amountIn,
uint amountOutMin,
address tokenFrom,
address tokenTo,
bool stable,
address to,
uint deadline
) external ensure(deadline) returns (uint[] 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, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
_safeTransferFrom(
routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]
);
_swap(amounts, routes, to);
}
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
route[] calldata routes,
address to,
uint deadline
) external ensure(deadline) returns (uint[] memory amounts) {
amounts = getAmountsOut(amountIn, routes);
require(amounts[amounts.length - 1] >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
_safeTransferFrom(
routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]
);
_swap(amounts, routes, to);
}
function swapExactETHForTokens(uint amountOutMin, route[] calldata routes, address to, uint deadline)
external
payable
ensure(deadline)
returns (uint[] memory amounts)
{
require(routes[0].from == address(weth), 'Router: INVALID_PATH');
amounts = getAmountsOut(msg.value, routes);
require(amounts[amounts.length - 1] >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
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(uint amountIn, uint amountOutMin, route[] calldata routes, address to, uint deadline)
external
ensure(deadline)
returns (uint[] memory amounts)
{
require(routes[routes.length - 1].to == address(weth), 'Router: INVALID_PATH');
amounts = getAmountsOut(amountIn, routes);
require(amounts[amounts.length - 1] >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
_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(
uint[] memory amounts,
route[] calldata routes,
address to,
uint deadline
) external ensure(deadline) returns (uint[] 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, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: 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))));
}
// **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens)****
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
bool stable,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) public ensure(deadline) returns (uint amountToken, uint 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,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH) {
address pair = pairFor(token, address(weth), stable);
uint value = approveMax ? type(uint).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[] memory routes, address _to) internal virtual {
for (uint i; i < routes.length; i++) {
(address input, address output,) = (routes[i].from, routes[i].to, routes[i].stable);
(address token0,) = sortTokens(input, output);
IPair pair = IPair(pairFor(routes[i].from, routes[i].to, routes[i].stable));
uint amountInput;
uint amountOutput;
{ // scope to avoid stack too deep errors
(uint reserve0, uint reserve1,) = pair.getReserves();
(uint reserveInput,) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput);
//(amountOutput,) = getAmountOut(amountInput, input, output, stable);
amountOutput = pair.getAmountOut(amountInput, input);
}
(uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(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(
uint amountIn,
uint amountOutMin,
route[] calldata routes,
address to,
uint deadline
) external ensure(deadline) {
_safeTransferFrom(
routes[0].from,
msg.sender,
pairFor(routes[0].from, routes[0].to, routes[0].stable),
amountIn
);
uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to);
_swapSupportingFeeOnTransferTokens(routes, to);
require(
IERC20(routes[routes.length - 1].to).balanceOf(to).sub(balanceBefore) >= amountOutMin,
'Router: INSUFFICIENT_OUTPUT_AMOUNT'
);
}
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
route[] calldata routes,
address to,
uint deadline
)
external
payable
ensure(deadline)
{
require(routes[0].from == address(weth), 'Router: INVALID_PATH');
uint amountIn = msg.value;
weth.deposit{value: amountIn}();
assert(weth.transfer(pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn));
uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to);
_swapSupportingFeeOnTransferTokens(routes, to);
require(
IERC20(routes[routes.length - 1].to).balanceOf(to).sub(balanceBefore) >= amountOutMin,
'Router: INSUFFICIENT_OUTPUT_AMOUNT'
);
}
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
route[] calldata routes,
address to,
uint deadline
)
external
ensure(deadline)
{
require(routes[routes.length - 1].to == address(weth), 'Router: INVALID_PATH');
_safeTransferFrom(
routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn
);
_swapSupportingFeeOnTransferTokens(routes, address(this));
uint amountOut = IERC20(address(weth)).balanceOf(address(this));
require(amountOut >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
weth.withdraw(amountOut);
_safeTransferETH(to, amountOut);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (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
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
interface IPair {
function burn(address to) external returns (uint amount0, uint amount1);
function claimFees() external returns (uint, uint);
function getAmountOut(uint amountIn, address tokenIn) external view returns (uint);
function getReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);
function mint(address to) external returns (uint liquidity);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
function stable() external view returns (bool);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function tokens() external returns (address, address);
function transferFrom(address src, address dst, uint amount) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
interface IPairFactory {
function admin() external view returns (address);
function feeManagers(address feeManager) external view returns (bool);
function allPairsLength() external view returns (uint);
function isPair(address pair) external view returns (bool);
function pairCodeHash() external pure returns (bytes32);
function getPair(address tokenA, address token, bool stable) external view returns (address);
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair);
function getInitializable() external view returns (address, address, bool);
function setPause(bool _state) external;
function isPaused() external view returns (bool);
function getFee(bool _stable) external view returns(uint256);
function getRealFee(address _pair) external view returns(uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
function balanceOf(address) external returns (uint);
}{
"evmVersion": "paris",
"optimizer": {
"enabled": true,
"runs": 10000
},
"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":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"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":"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":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60e06040523480156200001157600080fd5b50604051620052f2380380620052f28339810160408190526200003491620000d8565b6001600160a01b038216608081905260408051631355724960e31b81529051639aab9248916004808201926020929091908290030181865afa1580156200007f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a5919062000110565b60c0526001600160a01b031660a052506200012a565b80516001600160a01b0381168114620000d357600080fd5b919050565b60008060408385031215620000ec57600080fd5b620000f783620000bb565b91506200010760208401620000bb565b90509250929050565b6000602082840312156200012357600080fd5b5051919050565b60805160a05160c0516150c66200022c60003960006112450152600081816101b50152818161028201528181610b5501528181610e1a015281816110910152818161190b01528181611aa401528181611b320152818161211a015281816121c80152818161223c0152818161250a015281816126570152818161277101528181612e2d01528181612e6301528181612e9801528181612f46015281816130ce01528181613137015281816131bd01526135750152600081816104f701528181610f480152818161120a01528181611577015281816116bd0152818161293e01528181612af1015281816132fd01528181613af60152613bbb01526150c66000f3fe6080604052600436106101a55760003560e01c80637301e3c8116100e1578063b7e0d4c01161008a578063e2d9d4dc11610064578063e2d9d4dc14610539578063e5e31b1314610559578063f41766d814610589578063fe411f14146105a957600080fd5b8063b7e0d4c0146104d2578063c45a0155146104e5578063d7b0e0a51461051957600080fd5b80639881fcb4116100bb5780639881fcb41461047257806398a0fb3c14610492578063a32b1fcd146104b257600080fd5b80637301e3c81461041f57806376c727511461043f5780637af728c81461045257600080fd5b80634c1ee03e1161014e5780635e1e6325116101285780635e1e6325146103975780635e60dab5146103cc57806367ffb66a146103ec5780636cc1ae13146103ff57600080fd5b80634c1ee03e146102fc578063544caa561461031c5780635a47ddc31461035c57600080fd5b80633fc8cef31161017f5780633fc8cef3146102705780634386e63c146102bc578063448725b4146102dc57600080fd5b80630dede6c4146101e957806313dcfc591461022357806318a130861461025057600080fd5b366101e457336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101e2576101e261448b565b005b600080fd5b3480156101f557600080fd5b506102096102043660046144f0565b6105c9565b604080519283526020830191909152015b60405180910390f35b34801561022f57600080fd5b5061024361023e366004614575565b610841565b60405161021a91906145f0565b34801561025c57600080fd5b5061024361026b366004614679565b610af8565b34801561027c57600080fd5b506102a47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161021a565b3480156102c857600080fd5b506102096102d73660046146ec565b610ef9565b3480156102e857600080fd5b506102096102f736600461474e565b611086565b34801561030857600080fd5b506102a46103173660046147f8565b6111b0565b34801561032857600080fd5b5061033c610337366004614843565b611314565b604080516001600160a01b0393841681529290911660208301520161021a565b34801561036857600080fd5b5061037c61037736600461487c565b6113fd565b6040805193845260208401929092529082015260600161021a565b3480156103a357600080fd5b506103b76103b236600461490b565b611526565b6040805192835290151560208301520161021a565b3480156103d857600080fd5b506102096103e73660046147f8565b6117de565b6102436103fa366004614942565b6118b6565b34801561040b57600080fd5b506101e261041a366004614679565b611ccb565b34801561042b57600080fd5b5061024361043a366004614a4b565b611fc1565b6101e261044d366004614942565b6120c7565b34801561045e57600080fd5b506101e261046d366004614679565b6124af565b34801561047e57600080fd5b5061024361048d366004614b8d565b6127df565b34801561049e57600080fd5b5061037c6104ad366004614c3a565b612aa0565b3480156104be57600080fd5b506102096104cd366004614c95565b612cc5565b61037c6104e0366004614d51565b612dd1565b3480156104f157600080fd5b506102a47f000000000000000000000000000000000000000000000000000000000000000081565b34801561052557600080fd5b50610209610534366004614d51565b613074565b34801561054557600080fd5b5061020961055436600461474e565b6131b2565b34801561056557600080fd5b50610579610574366004614dac565b6132c2565b604051901515815260200161021a565b34801561059557600080fd5b506102436105a4366004614679565b613370565b3480156105b557600080fd5b506102096105c4366004614d51565b61351b565b60008082428110156106225760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a2045585049524544000000000000000000000000000000000060448201526064015b60405180910390fd5b600061062f8c8c8c6111b0565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af115801561069e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c29190614dc9565b6106cb57600080fd5b6040517f89afcb440000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015610730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107549190614de6565b9150915060006107648f8f611314565b509050806001600160a01b03168f6001600160a01b03161461078757818361078a565b82825b90975095508a8710156107df5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e540000006044820152606401610619565b8986101561082f5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e540000006044820152606401610619565b50505050509850989650505050505050565b606081428110156108945760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b604080516001808252818301909252600091816020015b60408051606081018252600080825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816108ab579050509050878160008151811061090c5761090c614e0a565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050868160008151811061094457610944614e0a565b6020026020010151602001906001600160a01b031690816001600160a01b031681525050858160008151811061097c5761097c614e0a565b602090810291909101015190151560409091015261099a8a826127df565b92508883600185516109ac9190614e68565b815181106109bc576109bc614e0a565b60200260200101511015610a385760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b610ae081600081518110610a4e57610a4e614e0a565b60200260200101516000015133610ac084600081518110610a7157610a71614e0a565b60200260200101516000015185600081518110610a9057610a90614e0a565b60200260200101516020015186600081518110610aaf57610aaf614e0a565b6020026020010151604001516111b0565b86600081518110610ad357610ad3614e0a565b6020026020010151613632565b610aeb838287613758565b5050979650505050505050565b60608142811015610b4b5760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686610b82600182614e68565b818110610b9157610b91614e0a565b9050606002016020016020810190610ba99190614dac565b6001600160a01b031614610bff5760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b610c5b888787808060200260200160405190810160405280939291908181526020016000905b82821015610c5157610c4260608302860136819003810190614e7b565b81526020019060010190610c25565b50505050506127df565b9150868260018451610c6d9190614e68565b81518110610c7d57610c7d614e0a565b60200260200101511015610cf95760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b610dbb86866000818110610d0f57610d0f614e0a565b610d259260206060909202019081019150614dac565b33610da889896000818110610d3c57610d3c614e0a565b610d529260206060909202019081019150614dac565b8a8a6000818110610d6557610d65614e0a565b9050606002016020016020810190610d7d9190614dac565b8b8b6000818110610d9057610d90614e0a565b90506060020160400160208101906103179190614e97565b85600081518110610ad357610ad3614e0a565b610e18828787808060200260200160405190810160405280939291908181526020016000905b82821015610e0d57610dfe60608302860136819003810190614e7b565b81526020019060010190610de1565b505050505030613758565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551610e569190614e68565b81518110610e6657610e66614e0a565b60200260200101516040518263ffffffff1660e01b8152600401610e8c91815260200190565b600060405180830381600087803b158015610ea657600080fd5b505af1158015610eba573d6000803e3d6000fd5b50505050610eee848360018551610ed19190614e68565b81518110610ee157610ee1614e0a565b60200260200101516139a6565b509695505050505050565b6040517f6801cc300000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301528315156044830152600091829182917f000000000000000000000000000000000000000000000000000000000000000090911690636801cc3090606401602060405180830381865afa158015610f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb59190614eb4565b90506001600160a01b038116610fd257600080925092505061107d565b600080610fe08989896117de565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110489190614ed1565b9050806110558489614eea565b61105f9190614f30565b95508061106c8389614eea565b6110769190614f30565b9450505050505b94509492505050565b60008060006110b68e7f00000000000000000000000000000000000000000000000000000000000000008f6111b0565b90506000876110c5578c6110e7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c481018790529091506001600160a01b0383169063d505accf9060e401600060405180830381600087803b15801561116f57600080fd5b505af1158015611183573d6000803e3d6000fd5b505050506111968f8f8f8f8f8f8f613074565b809450819550505050509b509b9950505050505050505050565b60008060006111bf8686611314565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015286151560f81b604882015291935091507f000000000000000000000000000000000000000000000000000000000000000090604901604051602081830303815290604052805190602001207f00000000000000000000000000000000000000000000000000000000000000006040516020016112d4939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209695505050505050565b600080826001600160a01b0316846001600160a01b0316036113785760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f41444452455353455300000000006044820152606401610619565b826001600160a01b0316846001600160a01b03161061139857828461139b565b83835b90925090506001600160a01b0382166113f65760405162461bcd60e51b815260206004820152601460248201527f526f757465723a205a45524f5f414444524553530000000000000000000000006044820152606401610619565b9250929050565b600080600083428110156114535760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6114628d8d8d8d8d8d8d613a8e565b909450925060006114748e8e8e6111b0565b90506114828e338388613632565b61148e8d338387613632565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af11580156114ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115139190614ed1565b9250505099509950999650505050505050565b6000806000611537858560016111b0565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b03828116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e49190614dc9565b15611676576040517ff140a35a000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561164f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116739190614ed1565b91505b611682878760006111b0565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529194507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015611706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172a9190614dc9565b156117bc576040517ff140a35a000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa158015611795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b99190614ed1565b90505b8082116117cb578060006117cf565b8160015b94509450505050935093915050565b60008060006117ed8686611314565b5090506000806117fe8888886111b0565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561183b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185f9190614f89565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826001600160a01b0316886001600160a01b0316146118a45780826118a7565b81815b90999098509650505050505050565b606081428110156119095760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061194657611946614e0a565b61195c9260206060909202019081019150614dac565b6001600160a01b0316146119b25760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b611a04348787808060200260200160405190810160405280939291908181526020016000905b82821015610c51576119f560608302860136819003810190614e7b565b815260200190600101906119d8565b9150868260018451611a169190614e68565b81518110611a2657611a26614e0a565b60200260200101511015611aa25760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db083600081518110611ae457611ae4614e0a565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b1757600080fd5b505af1158015611b2b573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb611bc988886000818110611b7557611b75614e0a565b611b8b9260206060909202019081019150614dac565b89896000818110611b9e57611b9e614e0a565b9050606002016020016020810190611bb69190614dac565b8a8a6000818110610d9057610d90614e0a565b84600081518110611bdc57611bdc614e0a565b60200260200101516040518363ffffffff1660e01b8152600401611c159291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015611c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c589190614dc9565b611c6457611c6461448b565b611cc1828787808060200260200160405190810160405280939291908181526020016000905b82821015611cb657611ca760608302860136819003810190614e7b565b81526020019060010190611c8a565b505050505086613758565b5095945050505050565b8042811015611d1c5760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b611d6585856000818110611d3257611d32614e0a565b611d489260206060909202019081019150614dac565b33611d5f88886000818110611b7557611b75614e0a565b8a613632565b60008585611d74600182614e68565b818110611d8357611d83614e0a565b9050606002016020016020810190611d9b9190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015611dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e209190614ed1565b9050611e7e8686808060200260200160405190810160405280939291908181526020016000905b82821015611e7357611e6460608302860136819003810190614e7b565b81526020019060010190611e47565b505050505085613d52565b86611f43828888611e90600182614e68565b818110611e9f57611e9f614e0a565b9050606002016020016020810190611eb79190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015291909116906370a08231906024015b602060405180830381865afa158015611f19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3d9190614ed1565b906140ff565b1015611fb75760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b5050505050505050565b606081428110156120145760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b61206a8686600081811061202a5761202a614e0a565b6120409260206060909202019081019150614dac565b3361205789896000818110610d3c57610d3c614e0a565b8a600081518110610ad357610ad3614e0a565b6120bc878787808060200260200160405190810160405280939291908181526020016000905b82821015611cb6576120ad60608302860136819003810190614e7b565b81526020019060010190612090565b509495945050505050565b80428110156121185760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168585600081811061215557612155614e0a565b61216b9260206060909202019081019150614dac565b6001600160a01b0316146121c15760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561222157600080fd5b505af1158015612235573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb61227f88886000818110611b7557611b75614e0a565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af11580156122e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123089190614dc9565b6123145761231461448b565b60008686612323600182614e68565b81811061233257612332614e0a565b905060600201602001602081019061234a9190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa1580156123ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cf9190614ed1565b905061242d8787808060200260200160405190810160405280939291908181526020016000905b828210156124225761241360608302860136819003810190614e7b565b815260200190600101906123f6565b505050505086613d52565b87611f4382898961243f600182614e68565b81811061244e5761244e614e0a565b90506060020160200160208101906124669190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015291909116906370a0823190602401611efc565b80428110156125005760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585612537600182614e68565b81811061254657612546614e0a565b905060600201602001602081019061255e9190614dac565b6001600160a01b0316146125b45760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b6125ca85856000818110611d3257611d32614e0a565b6126268585808060200260200160405190810160405280939291908181526020016000905b8282101561261b5761260c60608302860136819003810190614e7b565b815260200190600101906125ef565b505050505030613d52565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ca9190614ed1565b9050868110156127425760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156127bd57600080fd5b505af11580156127d1573d6000803e3d6000fd5b50505050611fb784826139a6565b60606001825110156128335760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b8151612840906001614fce565b67ffffffffffffffff811115612858576128586149a9565b604051908082528060200260200182016040528015612881578160200160208202803683370190505b509050828160008151811061289857612898614e0a565b60200260200101818152505060005b8251811015612a995760006129038483815181106128c7576128c7614e0a565b6020026020010151600001518584815181106128e5576128e5614e0a565b602002602001015160200151868581518110610aaf57610aaf614e0a565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015612987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ab9190614dc9565b15612a9057806001600160a01b031663f140a35a8484815181106129d1576129d1614e0a565b60200260200101518685815181106129eb576129eb614e0a565b6020026020010151600001516040518363ffffffff1660e01b8152600401612a269291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015612a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a679190614ed1565b83612a73846001614fce565b81518110612a8357612a83614e0a565b6020026020010181815250505b506001016128a7565b5092915050565b6040517f6801cc300000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152858116602483015284151560448301526000918291829182917f00000000000000000000000000000000000000000000000000000000000000001690636801cc3090606401602060405180830381865afa158015612b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5c9190614eb4565b9050600080806001600160a01b03841615612be657836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd39190614ed1565b9050612be08c8c8c6117de565b90935091505b82158015612bf2575081155b15612c23578896508795506103e8612c12612c0d888a614eea565b614112565b612c1c9190614e68565b9450612cb6565b6000612c308a85856141fa565b9050888111612c7857899750955085612c7184612c4d848b614eea565b612c579190614f30565b84612c62858b614eea565b612c6c9190614f30565b6142c4565b9550612cb4565b6000612c858a85876141fa565b9850899750889050612cb085612c9b8584614eea565b612ca59190614f30565b85612c62868c614eea565b9650505b505b50505050955095509592505050565b6000806000612cd58f8f8f6111b0565b9050600087612ce4578c612d06565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c481018790529091506001600160a01b0383169063d505accf9060e401600060405180830381600087803b158015612d8e57600080fd5b505af1158015612da2573d6000803e3d6000fd5b5050505050612db78f8f8f8f8f8f8f8f6105c9565b8093508194505050509c509c9a5050505050505050505050565b60008060008342811015612e275760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b612e568b7f00000000000000000000000000000000000000000000000000000000000000008c8c348d8d613a8e565b90945092506000612e888c7f00000000000000000000000000000000000000000000000000000000000000008d6111b0565b9050612e968c338388613632565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612ef157600080fd5b505af1158015612f05573d6000803e3d6000fd5b50506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015612f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb79190614dc9565b612fc357612fc361448b565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015613024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130489190614ed1565b92508334111561306557613065336130608634614e68565b6139a6565b50509750975097945050505050565b60008082428110156130c85760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6130f88a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6105c9565b90935091506131088a86856142da565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561318357600080fd5b505af1158015613197573d6000803e3d6000fd5b505050506131a585836139a6565b5097509795505050505050565b60008060006131e28e7f00000000000000000000000000000000000000000000000000000000000000008f6111b0565b90506000876131f1578c613213565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c481018790529091506001600160a01b0383169063d505accf9060e401600060405180830381600087803b15801561329b57600080fd5b505af11580156132af573d6000803e3d6000fd5b505050506111968f8f8f8f8f8f8f61351b565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015613346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336a9190614dc9565b92915050565b606081428110156133c35760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b613415888787808060200260200160405190810160405280939291908181526020016000905b82821015610c515761340660608302860136819003810190614e7b565b815260200190600101906133e9565b91508682600184516134279190614e68565b8151811061343757613437614e0a565b602002602001015110156134b35760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b6134c986866000818110610d0f57610d0f614e0a565b610eee828787808060200260200160405190810160405280939291908181526020016000905b82821015611cb65761350c60608302860136819003810190614e7b565b815260200190600101906134ef565b600080824281101561356f5760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b61359f8a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6105c9565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529194509250613108908b9087906001600160a01b038316906370a0823190602401602060405180830381865afa158015613609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362d9190614ed1565b6142da565b6000846001600160a01b03163b1161364957600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916136db9190615005565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190614dc9565b61375057600080fd5b505050505050565b60005b82518110156139a05760006137aa84838151811061377b5761377b614e0a565b60200260200101516000015185848151811061379957613799614e0a565b602002602001015160200151611314565b5090506000856137bb846001614fce565b815181106137cb576137cb614e0a565b60200260200101519050600080836001600160a01b03168786815181106137f4576137f4614e0a565b6020026020010151600001516001600160a01b0316146138165782600061381a565b6000835b9150915060006001885161382e9190614e68565b861061383a57866138ad565b6138ad88613849886001614fce565b8151811061385957613859614e0a565b602002602001015160000151898860016138739190614fce565b8151811061388357613883614e0a565b6020026020010151602001518a89600161389d9190614fce565b81518110610aaf57610aaf614e0a565b90506139008887815181106138c4576138c4614e0a565b6020026020010151600001518988815181106138e2576138e2614e0a565b6020026020010151602001518a8981518110610aaf57610aaf614e0a565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f19166020018201604052801561393d576020820181803683370190505b506040518563ffffffff1660e01b815260040161395d9493929190615021565b600060405180830381600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b50506001909701965061375b95505050505050565b50505050565b604080516000808252602082019092526001600160a01b0384169083906040516139d09190615005565b60006040518083038185875af1925050503d8060008114613a0d576040519150601f19603f3d011682016040523d82523d6000602084013e613a12565b606091505b5050905080613a895760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c454400000000000000000000000000000000000000000000000000000000006064820152608401610619565b505050565b60008083861015613a9e57600080fd5b82851015613aab57600080fd5b6040517f6801cc300000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152898116602483015288151560448301526000917f000000000000000000000000000000000000000000000000000000000000000090911690636801cc3090606401602060405180830381865afa158015613b3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b639190614eb4565b90506001600160a01b038116613c2b576040517f82dfdce40000000000000000000000000000000000000000000000000000000081526001600160a01b038b811660048301528a8116602483015289151560448301527f000000000000000000000000000000000000000000000000000000000000000016906382dfdce4906064016020604051808303816000875af1158015613c04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c289190614eb4565b90505b600080613c398c8c8c6117de565b91509150816000148015613c4b575080155b15613c5b57889450879350613d43565b6000613c688a84846141fa565b9050888111613ccc5786811015613cc15760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e540000006044820152606401610619565b899550935083613d41565b6000613cd98a84866141fa565b90508a811115613ceb57613ceb61448b565b88811015613d3b5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e540000006044820152606401610619565b95508894505b505b50505097509795505050505050565b60005b8251811015613a8957600080848381518110613d7357613d73614e0a565b602002602001015160000151858481518110613d9157613d91614e0a565b602002602001015160200151868581518110613daf57613daf614e0a565b50919350915060009050613dc38383611314565b5090506000613e19878681518110613ddd57613ddd614e0a565b602002602001015160000151888781518110613dfb57613dfb614e0a565b602002602001015160200151898881518110610aaf57610aaf614e0a565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e839190614f89565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506000866001600160a01b0316896001600160a01b031614613eca578183613ecd565b82825b506040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152919250613f1f918391908c16906370a0823190602401611efc565b6040517ff140a35a000000000000000000000000000000000000000000000000000000008152600481018290526001600160a01b038b811660248301529196509087169063f140a35a90604401602060405180830381865afa158015613f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fad9190614ed1565b9350505050600080856001600160a01b0316886001600160a01b031614613fd657826000613fda565b6000835b91509150600060018c51613fee9190614e68565b8a10613ffa578a61405d565b61405d8c6140098c6001614fce565b8151811061401957614019614e0a565b6020026020010151600001518d8c60016140339190614fce565b8151811061404357614043614e0a565b6020026020010151602001518e8d600161389d9190614fce565b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091529091506001600160a01b0387169063022c0d9f906140b89086908690869060248101615021565b600060405180830381600087803b1580156140d257600080fd5b505af11580156140e6573d6000803e3d6000fd5b50506001909b019a50613d559950505050505050505050565b600061410b8284614e68565b9392505050565b60008160000361412457506000919050565b60006001614131846143f7565b901c6001901b9050600181848161414a5761414a614f01565b048201901c9050600181848161416257614162614f01565b048201901c9050600181848161417a5761417a614f01565b048201901c9050600181848161419257614192614f01565b048201901c905060018184816141aa576141aa614f01565b048201901c905060018184816141c2576141c2614f01565b048201901c905060018184816141da576141da614f01565b048201901c905061410b818285816141f4576141f4614f01565b046142c4565b600080841161424b5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e5400000000006044820152606401610619565b60008311801561425b5750600082115b6142a75760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c495155494449545900006044820152606401610619565b826142b28386614eea565b6142bc9190614f30565b949350505050565b60008183106142d3578161410b565b5090919050565b6000836001600160a01b03163b116142f157600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161437b9190615005565b6000604051808303816000865af19150503d80600081146143b8576040519150601f19603f3d011682016040523d82523d6000602084013e6143bd565b606091505b50915091508180156143e75750805115806143e75750808060200190518101906143e79190614dc9565b6143f057600080fd5b5050505050565b600080608083901c1561440c57608092831c92015b604083901c1561441e57604092831c92015b602083901c1561443057602092831c92015b601083901c1561444257601092831c92015b600883901c1561445457600892831c92015b600483901c1561446657600492831c92015b600283901c1561447857600292831c92015b600183901c1561336a5760010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6001600160a01b03811681146144cf57600080fd5b50565b80356144dd816144ba565b919050565b80151581146144cf57600080fd5b600080600080600080600080610100898b03121561450d57600080fd5b8835614518816144ba565b97506020890135614528816144ba565b96506040890135614538816144e2565b9550606089013594506080890135935060a0890135925060c089013561455d816144ba565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a03121561459057600080fd5b873596506020880135955060408801356145a9816144ba565b945060608801356145b9816144ba565b935060808801356145c9816144e2565b925060a08801356145d9816144ba565b8092505060c0880135905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b818110156146285783518352928401929184019160010161460c565b50909695505050505050565b60008083601f84011261464657600080fd5b50813567ffffffffffffffff81111561465e57600080fd5b6020830191508360206060830285010111156113f657600080fd5b60008060008060008060a0878903121561469257600080fd5b8635955060208701359450604087013567ffffffffffffffff8111156146b757600080fd5b6146c389828a01614634565b90955093505060608701356146d7816144ba565b80925050608087013590509295509295509295565b6000806000806080858703121561470257600080fd5b843561470d816144ba565b9350602085013561471d816144ba565b9250604085013561472d816144e2565b9396929550929360600135925050565b803560ff811681146144dd57600080fd5b60008060008060008060008060008060006101608c8e03121561477057600080fd5b8b3561477b816144ba565b9a5060208c013561478b816144e2565b995060408c0135985060608c0135975060808c0135965060a08c01356147b0816144ba565b955060c08c0135945060e08c01356147c7816144e2565b93506147d66101008d0161473d565b92506101208c013591506101408c013590509295989b509295989b9093969950565b60008060006060848603121561480d57600080fd5b8335614818816144ba565b92506020840135614828816144ba565b91506040840135614838816144e2565b809150509250925092565b6000806040838503121561485657600080fd5b8235614861816144ba565b91506020830135614871816144ba565b809150509250929050565b60008060008060008060008060006101208a8c03121561489b57600080fd5b89356148a6816144ba565b985060208a01356148b6816144ba565b975060408a01356148c6816144e2565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a01356148f2816144ba565b809250506101008a013590509295985092959850929598565b60008060006060848603121561492057600080fd5b833592506020840135614932816144ba565b91506040840135614838816144ba565b60008060008060006080868803121561495a57600080fd5b85359450602086013567ffffffffffffffff81111561497857600080fd5b61498488828901614634565b9095509350506040860135614998816144ba565b949793965091946060013592915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a1f57614a1f6149a9565b604052919050565b600067ffffffffffffffff821115614a4157614a416149a9565b5060051b60200190565b600080600080600060808688031215614a6357600080fd5b853567ffffffffffffffff80821115614a7b57600080fd5b818801915088601f830112614a8f57600080fd5b81356020614aa4614a9f83614a27565b6149d8565b82815260059290921b8401810191818101908c841115614ac357600080fd5b948201945b83861015614ae157853582529482019490820190614ac8565b99505089013592505080821115614af757600080fd5b50614b0488828901614634565b90955093506149989050604087016144d2565b600060608284031215614b2957600080fd5b6040516060810181811067ffffffffffffffff82111715614b4c57614b4c6149a9565b6040529050808235614b5d816144ba565b81526020830135614b6d816144ba565b60208201526040830135614b80816144e2565b6040919091015292915050565b60008060408385031215614ba057600080fd5b8235915060208084013567ffffffffffffffff811115614bbf57600080fd5b8401601f81018613614bd057600080fd5b8035614bde614a9f82614a27565b808282526020820191506060602060608502860101935089841115614c0257600080fd5b6020850194505b83851015614c2a57614c1b8a86614b17565b83529384019391850191614c09565b5080955050505050509250929050565b600080600080600060a08688031215614c5257600080fd5b8535614c5d816144ba565b94506020860135614c6d816144ba565b93506040860135614c7d816144e2565b94979396509394606081013594506080013592915050565b6000806000806000806000806000806000806101808d8f031215614cb857600080fd5b8c35614cc3816144ba565b9b5060208d0135614cd3816144ba565b9a5060408d0135614ce3816144e2565b995060608d0135985060808d0135975060a08d0135965060c08d0135614d08816144ba565b955060e08d013594506101008d0135614d20816144e2565b9350614d2f6101208e0161473d565b92506101408d013591506101608d013590509295989b509295989b509295989b565b600080600080600080600060e0888a031215614d6c57600080fd5b8735614d77816144ba565b96506020880135614d87816144e2565b955060408801359450606088013593506080880135925060a08801356145d9816144ba565b600060208284031215614dbe57600080fd5b813561410b816144ba565b600060208284031215614ddb57600080fd5b815161410b816144e2565b60008060408385031215614df957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561336a5761336a614e39565b600060608284031215614e8d57600080fd5b61410b8383614b17565b600060208284031215614ea957600080fd5b813561410b816144e2565b600060208284031215614ec657600080fd5b815161410b816144ba565b600060208284031215614ee357600080fd5b5051919050565b808202811582820484141761336a5761336a614e39565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f66577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff811681146144dd57600080fd5b600080600060608486031215614f9e57600080fd5b614fa784614f6b565b9250614fb560208501614f6b565b9150604084015163ffffffff8116811461483857600080fd5b8082018082111561336a5761336a614e39565b60005b83811015614ffc578181015183820152602001614fe4565b50506000910152565b60008251615017818460208701614fe1565b9190910192915050565b8481528360208201526001600160a01b0383166040820152608060608201526000825180608084015261505b8160a0850160208701614fe1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160a0019594505050505056fea26469706673582212202bd8e7f06c47523f5431fdd4e38a2a33e102d8096407c20103b14a2a6289881664736f6c6343000816003300000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf7824000000000000000000000000fc00000000000000000000000000000000000006
Deployed Bytecode
0x6080604052600436106101a55760003560e01c80637301e3c8116100e1578063b7e0d4c01161008a578063e2d9d4dc11610064578063e2d9d4dc14610539578063e5e31b1314610559578063f41766d814610589578063fe411f14146105a957600080fd5b8063b7e0d4c0146104d2578063c45a0155146104e5578063d7b0e0a51461051957600080fd5b80639881fcb4116100bb5780639881fcb41461047257806398a0fb3c14610492578063a32b1fcd146104b257600080fd5b80637301e3c81461041f57806376c727511461043f5780637af728c81461045257600080fd5b80634c1ee03e1161014e5780635e1e6325116101285780635e1e6325146103975780635e60dab5146103cc57806367ffb66a146103ec5780636cc1ae13146103ff57600080fd5b80634c1ee03e146102fc578063544caa561461031c5780635a47ddc31461035c57600080fd5b80633fc8cef31161017f5780633fc8cef3146102705780634386e63c146102bc578063448725b4146102dc57600080fd5b80630dede6c4146101e957806313dcfc591461022357806318a130861461025057600080fd5b366101e457336001600160a01b037f000000000000000000000000fc0000000000000000000000000000000000000616146101e2576101e261448b565b005b600080fd5b3480156101f557600080fd5b506102096102043660046144f0565b6105c9565b604080519283526020830191909152015b60405180910390f35b34801561022f57600080fd5b5061024361023e366004614575565b610841565b60405161021a91906145f0565b34801561025c57600080fd5b5061024361026b366004614679565b610af8565b34801561027c57600080fd5b506102a47f000000000000000000000000fc0000000000000000000000000000000000000681565b6040516001600160a01b03909116815260200161021a565b3480156102c857600080fd5b506102096102d73660046146ec565b610ef9565b3480156102e857600080fd5b506102096102f736600461474e565b611086565b34801561030857600080fd5b506102a46103173660046147f8565b6111b0565b34801561032857600080fd5b5061033c610337366004614843565b611314565b604080516001600160a01b0393841681529290911660208301520161021a565b34801561036857600080fd5b5061037c61037736600461487c565b6113fd565b6040805193845260208401929092529082015260600161021a565b3480156103a357600080fd5b506103b76103b236600461490b565b611526565b6040805192835290151560208301520161021a565b3480156103d857600080fd5b506102096103e73660046147f8565b6117de565b6102436103fa366004614942565b6118b6565b34801561040b57600080fd5b506101e261041a366004614679565b611ccb565b34801561042b57600080fd5b5061024361043a366004614a4b565b611fc1565b6101e261044d366004614942565b6120c7565b34801561045e57600080fd5b506101e261046d366004614679565b6124af565b34801561047e57600080fd5b5061024361048d366004614b8d565b6127df565b34801561049e57600080fd5b5061037c6104ad366004614c3a565b612aa0565b3480156104be57600080fd5b506102096104cd366004614c95565b612cc5565b61037c6104e0366004614d51565b612dd1565b3480156104f157600080fd5b506102a47f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf782481565b34801561052557600080fd5b50610209610534366004614d51565b613074565b34801561054557600080fd5b5061020961055436600461474e565b6131b2565b34801561056557600080fd5b50610579610574366004614dac565b6132c2565b604051901515815260200161021a565b34801561059557600080fd5b506102436105a4366004614679565b613370565b3480156105b557600080fd5b506102096105c4366004614d51565b61351b565b60008082428110156106225760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a2045585049524544000000000000000000000000000000000060448201526064015b60405180910390fd5b600061062f8c8c8c6111b0565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af115801561069e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c29190614dc9565b6106cb57600080fd5b6040517f89afcb440000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015610730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107549190614de6565b9150915060006107648f8f611314565b509050806001600160a01b03168f6001600160a01b03161461078757818361078a565b82825b90975095508a8710156107df5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e540000006044820152606401610619565b8986101561082f5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e540000006044820152606401610619565b50505050509850989650505050505050565b606081428110156108945760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b604080516001808252818301909252600091816020015b60408051606081018252600080825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816108ab579050509050878160008151811061090c5761090c614e0a565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050868160008151811061094457610944614e0a565b6020026020010151602001906001600160a01b031690816001600160a01b031681525050858160008151811061097c5761097c614e0a565b602090810291909101015190151560409091015261099a8a826127df565b92508883600185516109ac9190614e68565b815181106109bc576109bc614e0a565b60200260200101511015610a385760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b610ae081600081518110610a4e57610a4e614e0a565b60200260200101516000015133610ac084600081518110610a7157610a71614e0a565b60200260200101516000015185600081518110610a9057610a90614e0a565b60200260200101516020015186600081518110610aaf57610aaf614e0a565b6020026020010151604001516111b0565b86600081518110610ad357610ad3614e0a565b6020026020010151613632565b610aeb838287613758565b5050979650505050505050565b60608142811015610b4b5760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6001600160a01b037f000000000000000000000000fc00000000000000000000000000000000000006168686610b82600182614e68565b818110610b9157610b91614e0a565b9050606002016020016020810190610ba99190614dac565b6001600160a01b031614610bff5760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b610c5b888787808060200260200160405190810160405280939291908181526020016000905b82821015610c5157610c4260608302860136819003810190614e7b565b81526020019060010190610c25565b50505050506127df565b9150868260018451610c6d9190614e68565b81518110610c7d57610c7d614e0a565b60200260200101511015610cf95760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b610dbb86866000818110610d0f57610d0f614e0a565b610d259260206060909202019081019150614dac565b33610da889896000818110610d3c57610d3c614e0a565b610d529260206060909202019081019150614dac565b8a8a6000818110610d6557610d65614e0a565b9050606002016020016020810190610d7d9190614dac565b8b8b6000818110610d9057610d90614e0a565b90506060020160400160208101906103179190614e97565b85600081518110610ad357610ad3614e0a565b610e18828787808060200260200160405190810160405280939291908181526020016000905b82821015610e0d57610dfe60608302860136819003810190614e7b565b81526020019060010190610de1565b505050505030613758565b7f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b0316632e1a7d4d8360018551610e569190614e68565b81518110610e6657610e66614e0a565b60200260200101516040518263ffffffff1660e01b8152600401610e8c91815260200190565b600060405180830381600087803b158015610ea657600080fd5b505af1158015610eba573d6000803e3d6000fd5b50505050610eee848360018551610ed19190614e68565b81518110610ee157610ee1614e0a565b60200260200101516139a6565b509695505050505050565b6040517f6801cc300000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301528315156044830152600091829182917f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf782490911690636801cc3090606401602060405180830381865afa158015610f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb59190614eb4565b90506001600160a01b038116610fd257600080925092505061107d565b600080610fe08989896117de565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110489190614ed1565b9050806110558489614eea565b61105f9190614f30565b95508061106c8389614eea565b6110769190614f30565b9450505050505b94509492505050565b60008060006110b68e7f000000000000000000000000fc000000000000000000000000000000000000068f6111b0565b90506000876110c5578c6110e7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c481018790529091506001600160a01b0383169063d505accf9060e401600060405180830381600087803b15801561116f57600080fd5b505af1158015611183573d6000803e3d6000fd5b505050506111968f8f8f8f8f8f8f613074565b809450819550505050509b509b9950505050505050505050565b60008060006111bf8686611314565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015286151560f81b604882015291935091507f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf782490604901604051602081830303815290604052805190602001207ff9be845b4767c45e75145bc3236fca103be5547d1d676c89bd60a7db9595bb326040516020016112d4939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209695505050505050565b600080826001600160a01b0316846001600160a01b0316036113785760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f41444452455353455300000000006044820152606401610619565b826001600160a01b0316846001600160a01b03161061139857828461139b565b83835b90925090506001600160a01b0382166113f65760405162461bcd60e51b815260206004820152601460248201527f526f757465723a205a45524f5f414444524553530000000000000000000000006044820152606401610619565b9250929050565b600080600083428110156114535760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6114628d8d8d8d8d8d8d613a8e565b909450925060006114748e8e8e6111b0565b90506114828e338388613632565b61148e8d338387613632565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af11580156114ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115139190614ed1565b9250505099509950999650505050505050565b6000806000611537858560016111b0565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b03828116600483015291925060009182917f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf78249091169063e5e31b1390602401602060405180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e49190614dc9565b15611676576040517ff140a35a000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561164f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116739190614ed1565b91505b611682878760006111b0565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529194507f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf78249091169063e5e31b1390602401602060405180830381865afa158015611706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172a9190614dc9565b156117bc576040517ff140a35a000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa158015611795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b99190614ed1565b90505b8082116117cb578060006117cf565b8160015b94509450505050935093915050565b60008060006117ed8686611314565b5090506000806117fe8888886111b0565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561183b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185f9190614f89565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826001600160a01b0316886001600160a01b0316146118a45780826118a7565b81815b90999098509650505050505050565b606081428110156119095760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b7f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b03168686600081811061194657611946614e0a565b61195c9260206060909202019081019150614dac565b6001600160a01b0316146119b25760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b611a04348787808060200260200160405190810160405280939291908181526020016000905b82821015610c51576119f560608302860136819003810190614e7b565b815260200190600101906119d8565b9150868260018451611a169190614e68565b81518110611a2657611a26614e0a565b60200260200101511015611aa25760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b7f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031663d0e30db083600081518110611ae457611ae4614e0a565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b1757600080fd5b505af1158015611b2b573d6000803e3d6000fd5b50505050507f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031663a9059cbb611bc988886000818110611b7557611b75614e0a565b611b8b9260206060909202019081019150614dac565b89896000818110611b9e57611b9e614e0a565b9050606002016020016020810190611bb69190614dac565b8a8a6000818110610d9057610d90614e0a565b84600081518110611bdc57611bdc614e0a565b60200260200101516040518363ffffffff1660e01b8152600401611c159291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015611c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c589190614dc9565b611c6457611c6461448b565b611cc1828787808060200260200160405190810160405280939291908181526020016000905b82821015611cb657611ca760608302860136819003810190614e7b565b81526020019060010190611c8a565b505050505086613758565b5095945050505050565b8042811015611d1c5760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b611d6585856000818110611d3257611d32614e0a565b611d489260206060909202019081019150614dac565b33611d5f88886000818110611b7557611b75614e0a565b8a613632565b60008585611d74600182614e68565b818110611d8357611d83614e0a565b9050606002016020016020810190611d9b9190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015611dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e209190614ed1565b9050611e7e8686808060200260200160405190810160405280939291908181526020016000905b82821015611e7357611e6460608302860136819003810190614e7b565b81526020019060010190611e47565b505050505085613d52565b86611f43828888611e90600182614e68565b818110611e9f57611e9f614e0a565b9050606002016020016020810190611eb79190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015291909116906370a08231906024015b602060405180830381865afa158015611f19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3d9190614ed1565b906140ff565b1015611fb75760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b5050505050505050565b606081428110156120145760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b61206a8686600081811061202a5761202a614e0a565b6120409260206060909202019081019150614dac565b3361205789896000818110610d3c57610d3c614e0a565b8a600081518110610ad357610ad3614e0a565b6120bc878787808060200260200160405190810160405280939291908181526020016000905b82821015611cb6576120ad60608302860136819003810190614e7b565b81526020019060010190612090565b509495945050505050565b80428110156121185760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b7f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b03168585600081811061215557612155614e0a565b61216b9260206060909202019081019150614dac565b6001600160a01b0316146121c15760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b60003490507f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561222157600080fd5b505af1158015612235573d6000803e3d6000fd5b50505050507f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031663a9059cbb61227f88886000818110611b7557611b75614e0a565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af11580156122e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123089190614dc9565b6123145761231461448b565b60008686612323600182614e68565b81811061233257612332614e0a565b905060600201602001602081019061234a9190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa1580156123ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cf9190614ed1565b905061242d8787808060200260200160405190810160405280939291908181526020016000905b828210156124225761241360608302860136819003810190614e7b565b815260200190600101906123f6565b505050505086613d52565b87611f4382898961243f600182614e68565b81811061244e5761244e614e0a565b90506060020160200160208101906124669190614dac565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015291909116906370a0823190602401611efc565b80428110156125005760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6001600160a01b037f000000000000000000000000fc00000000000000000000000000000000000006168585612537600182614e68565b81811061254657612546614e0a565b905060600201602001602081019061255e9190614dac565b6001600160a01b0316146125b45760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b6125ca85856000818110611d3257611d32614e0a565b6126268585808060200260200160405190810160405280939291908181526020016000905b8282101561261b5761260c60608302860136819003810190614e7b565b815260200190600101906125ef565b505050505030613d52565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b0316906370a0823190602401602060405180830381865afa1580156126a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ca9190614ed1565b9050868110156127425760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156127bd57600080fd5b505af11580156127d1573d6000803e3d6000fd5b50505050611fb784826139a6565b60606001825110156128335760405162461bcd60e51b815260206004820152601460248201527f526f757465723a20494e56414c49445f504154480000000000000000000000006044820152606401610619565b8151612840906001614fce565b67ffffffffffffffff811115612858576128586149a9565b604051908082528060200260200182016040528015612881578160200160208202803683370190505b509050828160008151811061289857612898614e0a565b60200260200101818152505060005b8251811015612a995760006129038483815181106128c7576128c7614e0a565b6020026020010151600001518584815181106128e5576128e5614e0a565b602002602001015160200151868581518110610aaf57610aaf614e0a565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192507f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf78249091169063e5e31b1390602401602060405180830381865afa158015612987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ab9190614dc9565b15612a9057806001600160a01b031663f140a35a8484815181106129d1576129d1614e0a565b60200260200101518685815181106129eb576129eb614e0a565b6020026020010151600001516040518363ffffffff1660e01b8152600401612a269291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015612a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a679190614ed1565b83612a73846001614fce565b81518110612a8357612a83614e0a565b6020026020010181815250505b506001016128a7565b5092915050565b6040517f6801cc300000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152858116602483015284151560448301526000918291829182917f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf78241690636801cc3090606401602060405180830381865afa158015612b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5c9190614eb4565b9050600080806001600160a01b03841615612be657836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd39190614ed1565b9050612be08c8c8c6117de565b90935091505b82158015612bf2575081155b15612c23578896508795506103e8612c12612c0d888a614eea565b614112565b612c1c9190614e68565b9450612cb6565b6000612c308a85856141fa565b9050888111612c7857899750955085612c7184612c4d848b614eea565b612c579190614f30565b84612c62858b614eea565b612c6c9190614f30565b6142c4565b9550612cb4565b6000612c858a85876141fa565b9850899750889050612cb085612c9b8584614eea565b612ca59190614f30565b85612c62868c614eea565b9650505b505b50505050955095509592505050565b6000806000612cd58f8f8f6111b0565b9050600087612ce4578c612d06565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c481018790529091506001600160a01b0383169063d505accf9060e401600060405180830381600087803b158015612d8e57600080fd5b505af1158015612da2573d6000803e3d6000fd5b5050505050612db78f8f8f8f8f8f8f8f6105c9565b8093508194505050509c509c9a5050505050505050505050565b60008060008342811015612e275760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b612e568b7f000000000000000000000000fc000000000000000000000000000000000000068c8c348d8d613a8e565b90945092506000612e888c7f000000000000000000000000fc000000000000000000000000000000000000068d6111b0565b9050612e968c338388613632565b7f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612ef157600080fd5b505af1158015612f05573d6000803e3d6000fd5b50506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018990527f000000000000000000000000fc0000000000000000000000000000000000000616935063a9059cbb925060440190506020604051808303816000875af1158015612f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb79190614dc9565b612fc357612fc361448b565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015613024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130489190614ed1565b92508334111561306557613065336130608634614e68565b6139a6565b50509750975097945050505050565b60008082428110156130c85760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b6130f88a7f000000000000000000000000fc000000000000000000000000000000000000068b8b8b8b308b6105c9565b90935091506131088a86856142da565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000fc000000000000000000000000000000000000066001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561318357600080fd5b505af1158015613197573d6000803e3d6000fd5b505050506131a585836139a6565b5097509795505050505050565b60008060006131e28e7f000000000000000000000000fc000000000000000000000000000000000000068f6111b0565b90506000876131f1578c613213565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c481018790529091506001600160a01b0383169063d505accf9060e401600060405180830381600087803b15801561329b57600080fd5b505af11580156132af573d6000803e3d6000fd5b505050506111968f8f8f8f8f8f8f61351b565b6040517fe5e31b130000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf78249091169063e5e31b1390602401602060405180830381865afa158015613346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336a9190614dc9565b92915050565b606081428110156133c35760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b613415888787808060200260200160405190810160405280939291908181526020016000905b82821015610c515761340660608302860136819003810190614e7b565b815260200190600101906133e9565b91508682600184516134279190614e68565b8151811061343757613437614e0a565b602002602001015110156134b35760405162461bcd60e51b815260206004820152602260248201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560448201527f4e540000000000000000000000000000000000000000000000000000000000006064820152608401610619565b6134c986866000818110610d0f57610d0f614e0a565b610eee828787808060200260200160405190810160405280939291908181526020016000905b82821015611cb65761350c60608302860136819003810190614e7b565b815260200190600101906134ef565b600080824281101561356f5760405162461bcd60e51b815260206004820152600f60248201527f526f757465723a204558504952454400000000000000000000000000000000006044820152606401610619565b61359f8a7f000000000000000000000000fc000000000000000000000000000000000000068b8b8b8b308b6105c9565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529194509250613108908b9087906001600160a01b038316906370a0823190602401602060405180830381865afa158015613609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362d9190614ed1565b6142da565b6000846001600160a01b03163b1161364957600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916136db9190615005565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190614dc9565b61375057600080fd5b505050505050565b60005b82518110156139a05760006137aa84838151811061377b5761377b614e0a565b60200260200101516000015185848151811061379957613799614e0a565b602002602001015160200151611314565b5090506000856137bb846001614fce565b815181106137cb576137cb614e0a565b60200260200101519050600080836001600160a01b03168786815181106137f4576137f4614e0a565b6020026020010151600001516001600160a01b0316146138165782600061381a565b6000835b9150915060006001885161382e9190614e68565b861061383a57866138ad565b6138ad88613849886001614fce565b8151811061385957613859614e0a565b602002602001015160000151898860016138739190614fce565b8151811061388357613883614e0a565b6020026020010151602001518a89600161389d9190614fce565b81518110610aaf57610aaf614e0a565b90506139008887815181106138c4576138c4614e0a565b6020026020010151600001518988815181106138e2576138e2614e0a565b6020026020010151602001518a8981518110610aaf57610aaf614e0a565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f19166020018201604052801561393d576020820181803683370190505b506040518563ffffffff1660e01b815260040161395d9493929190615021565b600060405180830381600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b50506001909701965061375b95505050505050565b50505050565b604080516000808252602082019092526001600160a01b0384169083906040516139d09190615005565b60006040518083038185875af1925050503d8060008114613a0d576040519150601f19603f3d011682016040523d82523d6000602084013e613a12565b606091505b5050905080613a895760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c454400000000000000000000000000000000000000000000000000000000006064820152608401610619565b505050565b60008083861015613a9e57600080fd5b82851015613aab57600080fd5b6040517f6801cc300000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152898116602483015288151560448301526000917f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf782490911690636801cc3090606401602060405180830381865afa158015613b3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b639190614eb4565b90506001600160a01b038116613c2b576040517f82dfdce40000000000000000000000000000000000000000000000000000000081526001600160a01b038b811660048301528a8116602483015289151560448301527f00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf782416906382dfdce4906064016020604051808303816000875af1158015613c04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c289190614eb4565b90505b600080613c398c8c8c6117de565b91509150816000148015613c4b575080155b15613c5b57889450879350613d43565b6000613c688a84846141fa565b9050888111613ccc5786811015613cc15760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e540000006044820152606401610619565b899550935083613d41565b6000613cd98a84866141fa565b90508a811115613ceb57613ceb61448b565b88811015613d3b5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e540000006044820152606401610619565b95508894505b505b50505097509795505050505050565b60005b8251811015613a8957600080848381518110613d7357613d73614e0a565b602002602001015160000151858481518110613d9157613d91614e0a565b602002602001015160200151868581518110613daf57613daf614e0a565b50919350915060009050613dc38383611314565b5090506000613e19878681518110613ddd57613ddd614e0a565b602002602001015160000151888781518110613dfb57613dfb614e0a565b602002602001015160200151898881518110610aaf57610aaf614e0a565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e839190614f89565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506000866001600160a01b0316896001600160a01b031614613eca578183613ecd565b82825b506040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152919250613f1f918391908c16906370a0823190602401611efc565b6040517ff140a35a000000000000000000000000000000000000000000000000000000008152600481018290526001600160a01b038b811660248301529196509087169063f140a35a90604401602060405180830381865afa158015613f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fad9190614ed1565b9350505050600080856001600160a01b0316886001600160a01b031614613fd657826000613fda565b6000835b91509150600060018c51613fee9190614e68565b8a10613ffa578a61405d565b61405d8c6140098c6001614fce565b8151811061401957614019614e0a565b6020026020010151600001518d8c60016140339190614fce565b8151811061404357614043614e0a565b6020026020010151602001518e8d600161389d9190614fce565b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091529091506001600160a01b0387169063022c0d9f906140b89086908690869060248101615021565b600060405180830381600087803b1580156140d257600080fd5b505af11580156140e6573d6000803e3d6000fd5b50506001909b019a50613d559950505050505050505050565b600061410b8284614e68565b9392505050565b60008160000361412457506000919050565b60006001614131846143f7565b901c6001901b9050600181848161414a5761414a614f01565b048201901c9050600181848161416257614162614f01565b048201901c9050600181848161417a5761417a614f01565b048201901c9050600181848161419257614192614f01565b048201901c905060018184816141aa576141aa614f01565b048201901c905060018184816141c2576141c2614f01565b048201901c905060018184816141da576141da614f01565b048201901c905061410b818285816141f4576141f4614f01565b046142c4565b600080841161424b5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e5400000000006044820152606401610619565b60008311801561425b5750600082115b6142a75760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c495155494449545900006044820152606401610619565b826142b28386614eea565b6142bc9190614f30565b949350505050565b60008183106142d3578161410b565b5090919050565b6000836001600160a01b03163b116142f157600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161437b9190615005565b6000604051808303816000865af19150503d80600081146143b8576040519150601f19603f3d011682016040523d82523d6000602084013e6143bd565b606091505b50915091508180156143e75750805115806143e75750808060200190518101906143e79190614dc9565b6143f057600080fd5b5050505050565b600080608083901c1561440c57608092831c92015b604083901c1561441e57604092831c92015b602083901c1561443057602092831c92015b601083901c1561444257601092831c92015b600883901c1561445457600892831c92015b600483901c1561446657600492831c92015b600283901c1561447857600292831c92015b600183901c1561336a5760010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6001600160a01b03811681146144cf57600080fd5b50565b80356144dd816144ba565b919050565b80151581146144cf57600080fd5b600080600080600080600080610100898b03121561450d57600080fd5b8835614518816144ba565b97506020890135614528816144ba565b96506040890135614538816144e2565b9550606089013594506080890135935060a0890135925060c089013561455d816144ba565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a03121561459057600080fd5b873596506020880135955060408801356145a9816144ba565b945060608801356145b9816144ba565b935060808801356145c9816144e2565b925060a08801356145d9816144ba565b8092505060c0880135905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b818110156146285783518352928401929184019160010161460c565b50909695505050505050565b60008083601f84011261464657600080fd5b50813567ffffffffffffffff81111561465e57600080fd5b6020830191508360206060830285010111156113f657600080fd5b60008060008060008060a0878903121561469257600080fd5b8635955060208701359450604087013567ffffffffffffffff8111156146b757600080fd5b6146c389828a01614634565b90955093505060608701356146d7816144ba565b80925050608087013590509295509295509295565b6000806000806080858703121561470257600080fd5b843561470d816144ba565b9350602085013561471d816144ba565b9250604085013561472d816144e2565b9396929550929360600135925050565b803560ff811681146144dd57600080fd5b60008060008060008060008060008060006101608c8e03121561477057600080fd5b8b3561477b816144ba565b9a5060208c013561478b816144e2565b995060408c0135985060608c0135975060808c0135965060a08c01356147b0816144ba565b955060c08c0135945060e08c01356147c7816144e2565b93506147d66101008d0161473d565b92506101208c013591506101408c013590509295989b509295989b9093969950565b60008060006060848603121561480d57600080fd5b8335614818816144ba565b92506020840135614828816144ba565b91506040840135614838816144e2565b809150509250925092565b6000806040838503121561485657600080fd5b8235614861816144ba565b91506020830135614871816144ba565b809150509250929050565b60008060008060008060008060006101208a8c03121561489b57600080fd5b89356148a6816144ba565b985060208a01356148b6816144ba565b975060408a01356148c6816144e2565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a01356148f2816144ba565b809250506101008a013590509295985092959850929598565b60008060006060848603121561492057600080fd5b833592506020840135614932816144ba565b91506040840135614838816144ba565b60008060008060006080868803121561495a57600080fd5b85359450602086013567ffffffffffffffff81111561497857600080fd5b61498488828901614634565b9095509350506040860135614998816144ba565b949793965091946060013592915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a1f57614a1f6149a9565b604052919050565b600067ffffffffffffffff821115614a4157614a416149a9565b5060051b60200190565b600080600080600060808688031215614a6357600080fd5b853567ffffffffffffffff80821115614a7b57600080fd5b818801915088601f830112614a8f57600080fd5b81356020614aa4614a9f83614a27565b6149d8565b82815260059290921b8401810191818101908c841115614ac357600080fd5b948201945b83861015614ae157853582529482019490820190614ac8565b99505089013592505080821115614af757600080fd5b50614b0488828901614634565b90955093506149989050604087016144d2565b600060608284031215614b2957600080fd5b6040516060810181811067ffffffffffffffff82111715614b4c57614b4c6149a9565b6040529050808235614b5d816144ba565b81526020830135614b6d816144ba565b60208201526040830135614b80816144e2565b6040919091015292915050565b60008060408385031215614ba057600080fd5b8235915060208084013567ffffffffffffffff811115614bbf57600080fd5b8401601f81018613614bd057600080fd5b8035614bde614a9f82614a27565b808282526020820191506060602060608502860101935089841115614c0257600080fd5b6020850194505b83851015614c2a57614c1b8a86614b17565b83529384019391850191614c09565b5080955050505050509250929050565b600080600080600060a08688031215614c5257600080fd5b8535614c5d816144ba565b94506020860135614c6d816144ba565b93506040860135614c7d816144e2565b94979396509394606081013594506080013592915050565b6000806000806000806000806000806000806101808d8f031215614cb857600080fd5b8c35614cc3816144ba565b9b5060208d0135614cd3816144ba565b9a5060408d0135614ce3816144e2565b995060608d0135985060808d0135975060a08d0135965060c08d0135614d08816144ba565b955060e08d013594506101008d0135614d20816144e2565b9350614d2f6101208e0161473d565b92506101408d013591506101608d013590509295989b509295989b509295989b565b600080600080600080600060e0888a031215614d6c57600080fd5b8735614d77816144ba565b96506020880135614d87816144e2565b955060408801359450606088013593506080880135925060a08801356145d9816144ba565b600060208284031215614dbe57600080fd5b813561410b816144ba565b600060208284031215614ddb57600080fd5b815161410b816144e2565b60008060408385031215614df957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561336a5761336a614e39565b600060608284031215614e8d57600080fd5b61410b8383614b17565b600060208284031215614ea957600080fd5b813561410b816144e2565b600060208284031215614ec657600080fd5b815161410b816144ba565b600060208284031215614ee357600080fd5b5051919050565b808202811582820484141761336a5761336a614e39565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f66577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff811681146144dd57600080fd5b600080600060608486031215614f9e57600080fd5b614fa784614f6b565b9250614fb560208501614f6b565b9150604084015163ffffffff8116811461483857600080fd5b8082018082111561336a5761336a614e39565b60005b83811015614ffc578181015183820152602001614fe4565b50506000910152565b60008251615017818460208701614fe1565b9190910192915050565b8481528360208201526001600160a01b0383166040820152608060608201526000825180608084015261505b8160a0850160208701614fe1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160a0019594505050505056fea26469706673582212202bd8e7f06c47523f5431fdd4e38a2a33e102d8096407c20103b14a2a6289881664736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf7824000000000000000000000000fc00000000000000000000000000000000000006
-----Decoded View---------------
Arg [0] : _factory (address): 0x12508dd9108Abab2c5fD8fC6E4984E46a3CF7824
Arg [1] : _weth (address): 0xFC00000000000000000000000000000000000006
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000012508dd9108abab2c5fd8fc6e4984e46a3cf7824
Arg [1] : 000000000000000000000000fc00000000000000000000000000000000000006
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.