ETH Price: $2,037.03 (+0.50%)

Contract

0xD0478Ab51B53A8aCE00a402e0f190bbe6B0Eb969
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Swap Exact ETH F...177996182023-07-29 15:34:23956 days ago1690644863IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0032793524.69578067
Swap Exact ETH F...177992002023-07-29 14:09:59956 days ago1690639799IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0044337833.38945357
Swap Exact ETH F...177991432023-07-29 13:58:23956 days ago1690639103IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0032289924.31654909
Swap Exact ETH F...177990462023-07-29 13:38:59956 days ago1690637939IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0031010423.35303141
Swap Exact ETH F...177989592023-07-29 13:21:35956 days ago1690636895IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0034635326.08281628
Swap Exact ETH F...177871162023-07-27 21:35:23958 days ago1690493723IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0042128231.73690707
Swap Exact ETH F...177869042023-07-27 20:51:47958 days ago1690491107IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0037339128.11894682
Swap Exact ETH F...177863022023-07-27 18:50:23958 days ago1690483823IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0067313850.27023501
Swap Exact ETH F...177798322023-07-26 21:06:47959 days ago1690405607IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0040475630.48092139
Swap Exact ETH F...176946002023-07-14 22:15:59971 days ago1689372959IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0018408813.86310198
Swap Exact ETH F...176892642023-07-14 4:14:59971 days ago1689308099IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0027565820.75898608
Swap Exact ETH F...176889292023-07-14 3:06:59971 days ago1689304019IN
0xD0478Ab5...e6B0Eb969
0.005 ETH0.0033144824.96486918
Swap Exact ETH F...176889192023-07-14 3:04:59971 days ago1689303899IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0038513825.69511155
Swap Exact ETH F...176066602023-07-02 13:36:59983 days ago1688305019IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0024251915.5849613
Swap Exact ETH F...176022712023-07-01 22:49:35984 days ago1688251775IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0024674715.85667627
Swap Exact ETH F...175825512023-06-29 4:22:23986 days ago1688012543IN
0xD0478Ab5...e6B0Eb969
0.0006 ETH0.0031214820.05797679
Swap Exact ETH F...175588522023-06-25 20:25:47990 days ago1687724747IN
0xD0478Ab5...e6B0Eb969
0.001 ETH0.0023870415.33867019
Swap Exact ETH F...175588322023-06-25 20:21:35990 days ago1687724495IN
0xD0478Ab5...e6B0Eb969
0.001 ETH0.0024489415.73640025
Swap Exact ETH F...175587592023-06-25 20:06:23990 days ago1687723583IN
0xD0478Ab5...e6B0Eb969
0.001 ETH0.0021222813.63842143
Swap Exact ETH F...175583452023-06-25 18:42:35990 days ago1687718555IN
0xD0478Ab5...e6B0Eb969
0.003 ETH0.0020981413.48329995
Swap Exact ETH F...175583152023-06-25 18:36:35990 days ago1687718195IN
0xD0478Ab5...e6B0Eb969
0.003 ETH0.0021297813.68662499
Swap Exact ETH F...175583042023-06-25 18:34:23990 days ago1687718063IN
0xD0478Ab5...e6B0Eb969
0.00001 ETH0.0020249413.50644493
Swap Exact ETH F...175551862023-06-25 8:03:47990 days ago1687680227IN
0xD0478Ab5...e6B0Eb969
0.00001 ETH0.0013492315.05034097
Swap Exact ETH F...175550772023-06-25 7:41:47990 days ago1687678907IN
0xD0478Ab5...e6B0Eb969
0.00001 ETH0.0014037715.65874606
Swap Exact ETH F...175497582023-06-24 13:44:59991 days ago1687614299IN
0xD0478Ab5...e6B0Eb969
0.000001 ETH0.0011652613
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Deposit177996182023-07-29 15:34:23956 days ago1690644863
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177992002023-07-29 14:09:59956 days ago1690639799
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177991432023-07-29 13:58:23956 days ago1690639103
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177990462023-07-29 13:38:59956 days ago1690637939
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177989592023-07-29 13:21:35956 days ago1690636895
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177871162023-07-27 21:35:23958 days ago1690493723
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177869042023-07-27 20:51:47958 days ago1690491107
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177863022023-07-27 18:50:23958 days ago1690483823
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit177798322023-07-26 21:06:47959 days ago1690405607
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit176946002023-07-14 22:15:59971 days ago1689372959
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit176892642023-07-14 4:14:59971 days ago1689308099
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit176889292023-07-14 3:06:59971 days ago1689304019
0xD0478Ab5...e6B0Eb969
0.005 ETH
Deposit176889192023-07-14 3:04:59971 days ago1689303899
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit176066602023-07-02 13:36:59983 days ago1688305019
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit176022712023-07-01 22:49:35984 days ago1688251775
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit175825512023-06-29 4:22:23986 days ago1688012543
0xD0478Ab5...e6B0Eb969
0.0006 ETH
Deposit175588522023-06-25 20:25:47990 days ago1687724747
0xD0478Ab5...e6B0Eb969
0.001 ETH
Deposit175588322023-06-25 20:21:35990 days ago1687724495
0xD0478Ab5...e6B0Eb969
0.001 ETH
Deposit175587592023-06-25 20:06:23990 days ago1687723583
0xD0478Ab5...e6B0Eb969
0.001 ETH
Deposit175583452023-06-25 18:42:35990 days ago1687718555
0xD0478Ab5...e6B0Eb969
0.003 ETH
Deposit175583152023-06-25 18:36:35990 days ago1687718195
0xD0478Ab5...e6B0Eb969
0.003 ETH
Deposit175583042023-06-25 18:34:23990 days ago1687718063
0xD0478Ab5...e6B0Eb969
0.00001 ETH
Deposit175551862023-06-25 8:03:47990 days ago1687680227
0xD0478Ab5...e6B0Eb969
0.00001 ETH
Deposit175550772023-06-25 7:41:47990 days ago1687678907
0xD0478Ab5...e6B0Eb969
0.00001 ETH
Deposit175497582023-06-24 13:44:59991 days ago1687614299
0xD0478Ab5...e6B0Eb969
0.000001 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BioRouter

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 99999 runs

Other Settings:
default evmVersion
File 1 of 2 : A.sol
pragma solidity 0.8.16;
// SPDX-License-Identifier: MIT

import {IERC20} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";

library TransferHelper {

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
    }
}

interface IBioFactory {
    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function createPair(address tokenA, address tokenB) external returns (address pair);
    function INIT_CODE_PAIR_HASH() external view returns(bytes32);
}


interface IBioPair {
    function transferFrom(address from, address to, uint value) external returns (bool);
    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}

library BioLibrary {

    // returns sorted token addresses, used to handle return values from pairs sorted in this order
    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
        require(tokenA != tokenB, 'BioLibrary: IDENTICAL_ADDRESSES');
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        require(token0 != address(0), 'BioLibrary: ZERO_ADDRESS');
    }

    // calculates the CREATE2 address for a pair without making any external calls
    function pairFor(address factory, address tokenA, address tokenB) internal view returns (address pair) {
        (address token0, address token1) = sortTokens(tokenA, tokenB);
        bytes32 init_code_hash = IBioFactory(factory).INIT_CODE_PAIR_HASH();
        pair = address(uint160(uint(keccak256(abi.encodePacked(
                hex'ff',
                factory,
                keccak256(abi.encodePacked(token0, token1)),
                init_code_hash // init code hash
            )))));
    }

    // fetches and sorts the reserves for a pair
    function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
        (address token0,) = sortTokens(tokenA, tokenB);
        pairFor(factory, tokenA, tokenB);
        (uint reserve0, uint reserve1,) = IBioPair(pairFor(factory, tokenA, tokenB)).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }

    // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
    function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
        require(amountA > 0, 'BioLibrary: INSUFFICIENT_AMOUNT');
        require(reserveA > 0 && reserveB > 0, 'BioLibrary: INSUFFICIENT_LIQUIDITY');
        amountB = amountA * reserveB / reserveA;
    }

    // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, bool isHolder) internal pure returns (uint amountOut) {
        require(amountIn > 0, 'BioLibrary: INSUFFICIENT_INPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'BioLibrary: INSUFFICIENT_LIQUIDITY');
        uint amountInWithFee = amountIn * (isHolder ? 9975 : 9950);
        uint numerator = amountInWithFee * reserveOut;
        uint denominator = (reserveIn * 10000) + amountInWithFee;
        amountOut = numerator / denominator;
    }

    // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut, bool isHolder) internal pure returns (uint amountIn) {
        require(amountOut > 0, 'BioLibrary: INSUFFICIENT_OUTPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'BioLibrary: INSUFFICIENT_LIQUIDITY');
        uint numerator = reserveIn * amountOut * 10000;
        uint denominator = (reserveOut - amountOut) * (isHolder ? 9975 : 9950);
        amountIn = (numerator / denominator) + 1;
    }

    // performs chained getAmountOut calculations on any number of pairs
    function getAmountsOut(address factory, uint amountIn, address[] memory path, bool isHolder) internal view returns (uint[] memory amounts) {
        require(path.length >= 2, 'BioLibrary: INVALID_PATH');
        amounts = new uint[](path.length);
        amounts[0] = amountIn;
        for (uint i = 0; i < path.length - 1; i++) {
            (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]);
            amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut, isHolder);
        }
    }

    // performs chained getAmountIn calculations on any number of pairs
    function getAmountsIn(address factory, uint amountOut, address[] memory path, bool isHolder) internal view returns (uint[] memory amounts) {
        require(path.length >= 2, 'BioLibrary: INVALID_PATH');
        amounts = new uint[](path.length);
        amounts[amounts.length - 1] = amountOut;
        for (uint i = path.length - 1; i > 0; i--) {
            (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]);
            amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut, isHolder);
        }
    }
}

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}


contract BioRouter {

    address public immutable factory;
    address public immutable WETH;
    address public immutable BIONIC;

    modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'BioRouter: EXPIRED');
        _;
    }

    constructor(address _factory, address _WETH, address _BIONIC) {
        factory = _factory;
        WETH = _WETH;
        BIONIC = _BIONIC;
    }

    receive() external payable {
        assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract
    }

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) internal virtual returns (uint amountA, uint amountB) {
        // create the pair if it doesn't exist yet
        if (IBioFactory(factory).getPair(tokenA, tokenB) == address(0)) {
            IBioFactory(factory).createPair(tokenA, tokenB);
        }
        (uint reserveA, uint reserveB) = BioLibrary.getReserves(factory, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint amountBOptimal = BioLibrary.quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, 'BioRouter: INSUFFICIENT_B_AMOUNT');
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint amountAOptimal = BioLibrary.quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, 'BioRouter: INSUFFICIENT_A_AMOUNT');
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = BioLibrary.pairFor(factory, tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
        liquidity = IBioPair(pair).mint(to);
    }
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external virtual payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
        (amountToken, amountETH) = _addLiquidity(
            token,
            WETH,
            amountTokenDesired,
            msg.value,
            amountTokenMin,
            amountETHMin
        );
        address pair = BioLibrary.pairFor(factory, token, WETH);
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        IWETH(WETH).deposit{value: amountETH}();
        assert(IWETH(WETH).transfer(pair, amountETH));
        liquidity = IBioPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
    }

    // **** REMOVE LIQUIDITY ****
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) public virtual ensure(deadline) returns (uint amountA, uint amountB) {
        address pair = BioLibrary.pairFor(factory, tokenA, tokenB);
        IBioPair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
        (uint amount0, uint amount1) = IBioPair(pair).burn(to);
        (address token0,) = BioLibrary.sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, 'BioRouter: INSUFFICIENT_A_AMOUNT');
        require(amountB >= amountBMin, 'BioRouter: INSUFFICIENT_B_AMOUNT');
    }
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) public virtual ensure(deadline) returns (uint amountToken, uint amountETH) {
        (amountToken, amountETH) = removeLiquidity(
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        TransferHelper.safeTransfer(token, to, amountToken);
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external virtual returns (uint amountA, uint amountB) {
        address pair = BioLibrary.pairFor(factory, tokenA, tokenB);
        uint value = approveMax ? type(uint256).max : liquidity;
        IBioPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline);
    }
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external virtual returns (uint amountToken, uint amountETH) {
        address pair = BioLibrary.pairFor(factory, token, WETH);
        uint value = approveMax ? type(uint256).max : liquidity;
        IBioPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

    // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) ****
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) public virtual ensure(deadline) returns (uint amountETH) {
        (, amountETH) = removeLiquidity(
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this)));
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external virtual returns (uint amountETH) {
        address pair = BioLibrary.pairFor(factory, token, WETH);
        uint value = approveMax ? type(uint256).max : liquidity;
        IBioPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(
            token, liquidity, amountTokenMin, amountETHMin, to, deadline
        );
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual {
        for (uint i = 0; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = BioLibrary.sortTokens(input, output);
            uint amountOut = amounts[i + 1];
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
            address to = i < path.length - 2 ? BioLibrary.pairFor(factory, output, path[i + 2]) : _to;
            IBioPair(BioLibrary.pairFor(factory, input, output)).swap(
                amount0Out, amount1Out, to, new bytes(0)
            );
        }
    }
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint[] memory amounts) {
        bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
        amounts = BioLibrary.getAmountsOut(factory, amountIn, path, isHolder);
        require(amounts[amounts.length - 1] >= amountOutMin, 'BioRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, BioLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint[] memory amounts) {
        bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
        amounts = BioLibrary.getAmountsIn(factory, amountOut, path, isHolder);
        require(amounts[0] <= amountInMax, 'BioRouter: EXCESSIVE_INPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, BioLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        virtual
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[0] == WETH, 'BioRouter: INVALID_PATH');
        bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
        amounts = BioLibrary.getAmountsOut(factory, msg.value, path, isHolder);
        require(amounts[amounts.length - 1] >= amountOutMin, 'BioRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(BioLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
    }
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        virtual
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[path.length - 1] == WETH, 'BioRouter: INVALID_PATH');
        bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
        amounts = BioLibrary.getAmountsIn(factory, amountOut, path, isHolder);
        require(amounts[0] <= amountInMax, 'BioRouter: EXCESSIVE_INPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, BioLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
    }
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        virtual
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[path.length - 1] == WETH, 'BioRouter: INVALID_PATH');
        bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
        amounts = BioLibrary.getAmountsOut(factory, amountIn, path, isHolder);
        require(amounts[amounts.length - 1] >= amountOutMin, 'BioRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, BioLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
    }
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        virtual
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[0] == WETH, 'BioRouter: INVALID_PATH');
        bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
        amounts = BioLibrary.getAmountsIn(factory, amountOut, path, isHolder);
        require(amounts[0] <= msg.value, 'BioRouter: EXCESSIVE_INPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(BioLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
        // refund dust eth, if any
        if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]);
    }

    // **** SWAP (supporting fee-on-transfer tokens) ****
    // requires the initial amount to have already been sent to the first pair
    function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual {
        for (uint i = 0; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = BioLibrary.sortTokens(input, output);
            IBioPair pair = IBioPair(BioLibrary.pairFor(factory, input, output));
            uint amountInput;
            uint amountOutput;
            { // scope to avoid stack too deep errors
            (uint reserve0, uint reserve1,) = pair.getReserves();
            (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
            amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput;
            bool isHolder = IERC20(BIONIC).balanceOf(msg.sender) > 0;
            amountOutput = BioLibrary.getAmountOut(amountInput, reserveInput, reserveOutput, isHolder);
            }
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0));
            address to = i < path.length - 2 ? BioLibrary.pairFor(factory, output, path[i + 2]) : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) {
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, BioLibrary.pairFor(factory, path[0], path[1]), amountIn
        );
        uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin,
            'BioRouter: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        virtual
        payable
        ensure(deadline)
    {
        require(path[0] == WETH, 'BioRouter: INVALID_PATH');
        uint amountIn = msg.value;
        IWETH(WETH).deposit{value: amountIn}();
        assert(IWETH(WETH).transfer(BioLibrary.pairFor(factory, path[0], path[1]), amountIn));
        uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin,
            'BioRouter: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        virtual
        ensure(deadline)
    {
        require(path[path.length - 1] == WETH, 'BioRouter: INVALID_PATH');
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, BioLibrary.pairFor(factory, path[0], path[1]), amountIn
        );
        _swapSupportingFeeOnTransferTokens(path, address(this));
        uint amountOut = IERC20(WETH).balanceOf(address(this));
        require(amountOut >= amountOutMin, 'BioRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).withdraw(amountOut);
        TransferHelper.safeTransferETH(to, amountOut);
    }

    // **** LIBRARY FUNCTIONS ****
    function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual returns (uint amountB) {
        return BioLibrary.quote(amountA, reserveA, reserveB);
    }

    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, bool isHolder)
        public
        pure
        virtual
        returns (uint amountOut)
    {
        return BioLibrary.getAmountOut(amountIn, reserveIn, reserveOut, isHolder);
    }

    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut, bool isHolder)
        public
        pure
        virtual
        returns (uint amountIn)
    {
        return BioLibrary.getAmountIn(amountOut, reserveIn, reserveOut, isHolder);
    }

    function getAmountsOut(uint amountIn, address[] memory path, bool isHolder)
        public
        view
        virtual
        returns (uint[] memory amounts)
    {
        return BioLibrary.getAmountsOut(factory, amountIn, path, isHolder);
    }

    function getAmountsIn(uint amountOut, address[] memory path, bool isHolder)
        public
        view
        virtual
        returns (uint[] memory amounts)
    {
        return BioLibrary.getAmountsIn(factory, amountOut, path, isHolder);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 99999
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_BIONIC","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BIONIC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"bool","name":"isHolder","type":"bool"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"bool","name":"isHolder","type":"bool"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isHolder","type":"bool"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isHolder","type":"bool"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040523480156200001157600080fd5b5060405162005cab38038062005cab83398101604081905262000034916200006f565b6001600160a01b0392831660805290821660a0521660c052620000b9565b80516001600160a01b03811681146200006a57600080fd5b919050565b6000806000606084860312156200008557600080fd5b620000908462000052565b9250620000a06020850162000052565b9150620000b06040850162000052565b90509250925092565b60805160a05160c051615a256200028660003960008181610540015281816108c001528181610e3c015281816111b101528181611d2f01528181612192015281816133e501526146af0152600081816101b7015281816103e50152818161060101528181610669015281816107aa01528181610b4c0152818161109b015281816113550152818161188f015281816119e201528181611b2301528181611c0d01528181611eb701528181611f520152818161239a015281816124910152818161258401528181612665015281816126e601528181612cbf01528181612fc80152818161301e015281816130520152818161311a015281816132c30152818161356101526135fc0152600081816104b1015281816106f70152818161093301528181610a7701528181610c4301528181610eaf015281816112240152818161133301528181611512015281816117e601528181611da201528181611f910152818161220501528181612725015281816129fc01528181612c9d01528181612e6e01528181612ffc015281816134580152818161363b01528181613fee0152818161403e015281816144c00152818161479701528181614cdb01528181614db00152614e270152615a256000f3fe60806040526004361061019a5760003560e01c80638803dbee116100e1578063baa2abde1161008a578063e8e3370011610064578063e8e33700146104f3578063f27999731461052e578063f305d71914610562578063fb3bdb411461057557600080fd5b8063baa2abde1461047f578063c45a01551461049f578063ded9382a146104d357600080fd5b8063ad615dec116100bb578063ad615dec1461042c578063af2979eb1461044c578063b6f9de951461046c57600080fd5b80638803dbee14610393578063a5ff0d12146103b3578063ad5c4648146103d357600080fd5b80634a25d94a11610143578063684ab99b1161011d578063684ab99b14610340578063791ac947146103605780637ff36ab51461038057600080fd5b80634a25d94a146102e05780635b0d5984146103005780635c11d7951461032057600080fd5b80632195995c116101745780632195995c146102725780632e08a6ee1461029257806338ed1739146102c057600080fd5b806302751cec146101eb57806312a1c5f11461022557806318cbafe51461025257600080fd5b366101e6573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101e4576101e46150a3565b005b600080fd5b3480156101f757600080fd5b5061020b610206366004615107565b610588565b604080519283526020830191909152015b60405180910390f35b34801561023157600080fd5b506102456102403660046151ad565b6106f0565b60405161021c91906152ac565b34801561025e57600080fd5b5061024561026d366004615335565b610726565b34801561027e57600080fd5b5061020b61028d3660046153b9565b610c39565b34801561029e57600080fd5b506102b26102ad366004615463565b610d70565b60405190815260200161021c565b3480156102cc57600080fd5b506102456102db366004615335565b610d87565b3480156102ec57600080fd5b506102456102fb366004615335565b611017565b34801561030c57600080fd5b506102b261031b3660046154a4565b61132b565b34801561032c57600080fd5b506101e461033b366004615335565b611476565b34801561034c57600080fd5b5061024561035b3660046151ad565b6117df565b34801561036c57600080fd5b506101e461037b366004615335565b61180d565b61024561038e36600461553a565b611b9e565b34801561039f57600080fd5b506102456103ae366004615335565b6120dd565b3480156103bf57600080fd5b506102b26103ce366004615463565b61230c565b3480156103df57600080fd5b506104077f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b34801561043857600080fd5b506102b26104473660046155a1565b61231a565b34801561045857600080fd5b506102b2610467366004615107565b612327565b6101e461047a36600461553a565b612517565b34801561048b57600080fd5b5061020b61049a3660046155cd565b612987565b3480156104ab57600080fd5b506104077f000000000000000000000000000000000000000000000000000000000000000081565b3480156104df57600080fd5b5061020b6104ee3660046154a4565b612c93565b3480156104ff57600080fd5b5061051361050e36600461563f565b612de4565b6040805193845260208401929092529082015260600161021c565b34801561053a57600080fd5b506104077f000000000000000000000000000000000000000000000000000000000000000081565b610513610570366004615107565b612f52565b61024561058336600461553a565b613254565b60008082428110156105fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064015b60405180910390fd5b61062a897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a612987565b909350915061063a8986856137a0565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b505050506106e48583613910565b50965096945050505050565b606061071e7f0000000000000000000000000000000000000000000000000000000000000000858585613a1f565b949350505050565b60608142811015610793576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001686866107d76001826156ea565b8181106107e6576107e6615703565b90506020020160208101906107fb9190615732565b73ffffffffffffffffffffffffffffffffffffffff1614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092b9190615756565b11905061098e7f00000000000000000000000000000000000000000000000000000000000000008a898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250613a1f915050565b92508783600185516109a091906156ea565b815181106109b0576109b0615703565b60200260200101511015610a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b610b0b87876000818110610a5c57610a5c615703565b9050602002016020810190610a719190615732565b33610aeb7f00000000000000000000000000000000000000000000000000000000000000008b8b6000818110610aa957610aa9615703565b9050602002016020810190610abe9190615732565b8c8c6001818110610ad157610ad1615703565b9050602002016020810190610ae69190615732565b613bc6565b86600081518110610afe57610afe615703565b6020026020010151613d53565b610b4a83888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613ef1915050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d8460018651610b9591906156ea565b81518110610ba557610ba5615703565b60200260200101516040518263ffffffff1660e01b8152600401610bcb91815260200190565b600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b50505050610c2d858460018651610c1091906156ea565b81518110610c2057610c20615703565b6020026020010151613910565b50509695505050505050565b6000806000610c697f00000000000000000000000000000000000000000000000000000000000000008f8f613bc6565b9050600087610c78578c610c9a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015610d2f57600080fd5b505af1158015610d43573d6000803e3d6000fd5b50505050610d568f8f8f8f8f8f8f612987565b809450819550505050509b509b9950505050505050505050565b6000610d7e85858585614120565b95945050505050565b60608142811015610df4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610e83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea79190615756565b119050610f0a7f00000000000000000000000000000000000000000000000000000000000000008a898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250613a1f915050565b9250878360018551610f1c91906156ea565b81518110610f2c57610f2c615703565b60200260200101511015610fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b610fd887876000818110610a5c57610a5c615703565b610c2d838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613ef1915050565b60608142811015611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001686866110c86001826156ea565b8181106110d7576110d7615703565b90506020020160208101906110ec9190615732565b73ffffffffffffffffffffffffffffffffffffffff1614611169576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156111f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121c9190615756565b11905061127f7f00000000000000000000000000000000000000000000000000000000000000008a8989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792506142af915050565b9250878360008151811061129557611295615703565b60200260200101511115610a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f42696f526f757465723a204558434553534956455f494e5055545f414d4f554e60448201527f540000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6000806113797f00000000000000000000000000000000000000000000000000000000000000008d7f0000000000000000000000000000000000000000000000000000000000000000613bc6565b9050600086611388578b6113aa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018a905260ff8816608482015260a4810187905260c4810186905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b15801561143f57600080fd5b505af1158015611453573d6000803e3d6000fd5b505050506114658d8d8d8d8d8d612327565b9d9c50505050505050505050505050565b80428110156114e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b611572858560008181106114f7576114f7615703565b905060200201602081019061150c9190615732565b3361156c7f00000000000000000000000000000000000000000000000000000000000000008989600081811061154457611544615703565b90506020020160208101906115599190615732565b8a8a6001818110610ad157610ad1615703565b8a613d53565b600085856115816001826156ea565b81811061159057611590615703565b90506020020160208101906115a59190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015291909116906370a0823190602401602060405180830381865afa158015611613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116379190615756565b905061167786868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525088925061444b915050565b868187876116866001826156ea565b81811061169557611695615703565b90506020020160208101906116aa9190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015291909116906370a08231906024015b602060405180830381865afa158015611719573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173d9190615756565b61174791906156ea565b10156117d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b5050505050505050565b606061071e7f00000000000000000000000000000000000000000000000000000000000000008585856142af565b8042811015611878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685856118bc6001826156ea565b8181106118cb576118cb615703565b90506020020160208101906118e09190615732565b73ffffffffffffffffffffffffffffffffffffffff161461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b611973858560008181106114f7576114f7615703565b6119b185858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525030925061444b915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611a3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a629190615756565b905086811015611af4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015611b7c57600080fd5b505af1158015611b90573d6000803e3d6000fd5b505050506117d58482613910565b60608142811015611c0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1686866000818110611c5557611c55615703565b9050602002016020810190611c6a9190615732565b73ffffffffffffffffffffffffffffffffffffffff1614611ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9a9190615756565b119050611dfd7f000000000000000000000000000000000000000000000000000000000000000034898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250613a1f915050565b9250878360018551611e0f91906156ea565b81518110611e1f57611e1f615703565b60200260200101511015611eb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db084600081518110611f0457611f04615703565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f3757600080fd5b505af1158015611f4b573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb611feb7f00000000000000000000000000000000000000000000000000000000000000008a8a6000818110611fc357611fc3615703565b9050602002016020810190611fd89190615732565b8b8b6001818110610ad157610ad1615703565b85600081518110611ffe57611ffe615703565b60200260200101516040518363ffffffff1660e01b815260040161204492919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015612063573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612087919061576f565b612093576120936150a3565b6120d2838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613ef1915050565b505095945050505050565b6060814281101561214a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156121d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fd9190615756565b1190506122607f00000000000000000000000000000000000000000000000000000000000000008a8989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792506142af915050565b9250878360008151811061227657612276615703565b60200260200101511115610fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f42696f526f757465723a204558434553534956455f494e5055545f414d4f554e60448201527f540000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6000610d7e85858585614879565b600061071e848484614a0d565b60008142811015612394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6123c3887f00000000000000000000000000000000000000000000000000000000000000008989893089612987565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290935061246291508990869073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245d9190615756565b6137a0565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156124ea57600080fd5b505af11580156124fe573d6000803e3d6000fd5b5050505061250c8483613910565b509695505050505050565b8042811015612582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16858560008181106125cc576125cc615703565b90506020020160208101906125e19190615732565b73ffffffffffffffffffffffffffffffffffffffff161461265e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b60003490507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156126cb57600080fd5b505af11580156126df573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6127577f00000000000000000000000000000000000000000000000000000000000000008989600081811061154457611544615703565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af11580156127c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ed919061576f565b6127f9576127f96150a3565b600086866128086001826156ea565b81811061281757612817615703565b905060200201602081019061282c9190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291909116906370a0823190602401602060405180830381865afa15801561289a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128be9190615756565b90506128fe87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525089925061444b915050565b8781888861290d6001826156ea565b81811061291c5761291c615703565b90506020020160208101906129319190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015291909116906370a08231906024016116fc565b60008082428110156129f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6000612a227f00000000000000000000000000000000000000000000000000000000000000008c8c613bc6565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af1158015612a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac2919061576f565b506040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015612b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b59919061578c565b915091506000612b698e8e614b29565b5090508073ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff1614612ba6578183612ba9565b82825b90975095508a871015612c18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f415f414d4f554e5460448201526064016105f2565b89861015612c82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f425f414d4f554e5460448201526064016105f2565b505050505097509795505050505050565b6000806000612ce37f00000000000000000000000000000000000000000000000000000000000000008e7f0000000000000000000000000000000000000000000000000000000000000000613bc6565b9050600087612cf2578c612d14565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015612da957600080fd5b505af1158015612dbd573d6000803e3d6000fd5b50505050612dcf8e8e8e8e8e8e610588565b909f909e509c50505050505050505050505050565b60008060008342811015612e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b612e628c8c8c8c8c8c614c87565b90945092506000612e947f00000000000000000000000000000000000000000000000000000000000000008e8e613bc6565b9050612ea28d338388613d53565b612eae8c338387613d53565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af1158015612f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f409190615756565b92505050985098509895505050505050565b60008060008342811015612fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b612ff08a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c614c87565b909450925060006130427f00000000000000000000000000000000000000000000000000000000000000008c7f0000000000000000000000000000000000000000000000000000000000000000613bc6565b90506130508b338388613d53565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130b857600080fd5b505af11580156130cc573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015613167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318b919061576f565b613197576131976150a3565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af1158015613205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132299190615756565b925083341115613246576132463361324186346156ea565b613910565b505096509650969350505050565b606081428110156132c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168686600081811061330b5761330b615703565b90506020020160208101906133209190615732565b73ffffffffffffffffffffffffffffffffffffffff161461339d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561342c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134509190615756565b1190506134b37f0000000000000000000000000000000000000000000000000000000000000000898989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792506142af915050565b925034836000815181106134c9576134c9615703565b6020026020010151111561355f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f42696f526f757465723a204558434553534956455f494e5055545f414d4f554e60448201527f540000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0846000815181106135ae576135ae615703565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156135e157600080fd5b505af11580156135f5573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61366d7f00000000000000000000000000000000000000000000000000000000000000008a8a6000818110611fc357611fc3615703565b8560008151811061368057613680615703565b60200260200101516040518363ffffffff1660e01b81526004016136c692919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af11580156136e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613709919061576f565b613715576137156150a3565b613754838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613ef1915050565b8260008151811061376757613767615703565b60200260200101513411156120d2576120d2338460008151811061378d5761378d615703565b60200260200101513461324191906156ea565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161383791906157d4565b6000604051808303816000865af19150503d8060008114613874576040519150601f19603f3d011682016040523d82523d6000602084013e613879565b606091505b50915091508180156138a35750805115806138a35750808060200190518101906138a3919061576f565b613909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016105f2565b5050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161394791906157d4565b60006040518083038185875af1925050503d8060008114613984576040519150601f19603f3d011682016040523d82523d6000602084013e613989565b606091505b5050905080613a1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c4544000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b505050565b6060600283511015613a8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f42696f4c6962726172793a20494e56414c49445f50415448000000000000000060448201526064016105f2565b825167ffffffffffffffff811115613aa757613aa7615165565b604051908082528060200260200182016040528015613ad0578160200160208202803683370190505b5090508381600081518110613ae757613ae7615703565b60200260200101818152505060005b60018451613b0491906156ea565b811015613bbd57600080613b5788878581518110613b2457613b24615703565b602002602001015188866001613b3a91906157f0565b81518110613b4a57613b4a615703565b6020026020010151614f98565b91509150613b80848481518110613b7057613b70615703565b6020026020010151838388614120565b84613b8c8560016157f0565b81518110613b9c57613b9c615703565b60200260200101818152505050508080613bb590615803565b915050613af6565b50949350505050565b6000806000613bd58585614b29565b9150915060008673ffffffffffffffffffffffffffffffffffffffff16635855a25a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4a9190615756565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086811b8216602084015285901b16603482015290915087906048016040516020818303038152906040528051906020012082604051602001613d12939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120979650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691613df291906157d4565b6000604051808303816000865af19150503d8060008114613e2f576040519150601f19603f3d011682016040523d82523d6000602084013e613e34565b606091505b5091509150818015613e5e575080511580613e5e575080806020019051810190613e5e919061576f565b613ee9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160448201527f494c45440000000000000000000000000000000000000000000000000000000060648201526084016105f2565b505050505050565b60005b60018351613f0291906156ea565b81101561411a57600080848381518110613f1e57613f1e615703565b602002602001015185846001613f3491906157f0565b81518110613f4457613f44615703565b6020026020010151915091506000613f5c8383614b29565b509050600087613f6d8660016157f0565b81518110613f7d57613f7d615703565b602002602001015190506000808373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614613fc557826000613fc9565b6000835b91509150600060028a51613fdd91906156ea565b8810613fe95788614037565b6140377f0000000000000000000000000000000000000000000000000000000000000000878c61401a8c60026157f0565b8151811061402a5761402a615703565b6020026020010151613bc6565b90506140647f00000000000000000000000000000000000000000000000000000000000000008888613bc6565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f84848460006040519080825280601f01601f1916602001820160405280156140ae576020820181803683370190505b506040518563ffffffff1660e01b81526004016140ce949392919061583b565b600060405180830381600087803b1580156140e857600080fd5b505af11580156140fc573d6000803e3d6000fd5b5050505050505050505050808061411290615803565b915050613ef4565b50505050565b60008085116141b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f4c6962726172793a20494e53554646494349454e545f494e5055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b6000841180156141c15750600083115b61424d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f42696f4c6962726172793a20494e53554646494349454e545f4c49515549444960448201527f545900000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b60008261425c576126de614260565b6126f75b61426e9061ffff16876158b7565b9050600061427c85836158b7565b905060008261428d886127106158b7565b61429791906157f0565b90506142a381836158f4565b98975050505050505050565b606060028351101561431d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f42696f4c6962726172793a20494e56414c49445f50415448000000000000000060448201526064016105f2565b825167ffffffffffffffff81111561433757614337615165565b604051908082528060200260200182016040528015614360578160200160208202803683370190505b50905083816001835161437391906156ea565b8151811061438357614383615703565b60200260200101818152505060006001845161439f91906156ea565b90505b8015613bbd576000806143e588876143bb6001876156ea565b815181106143cb576143cb615703565b6020026020010151888681518110613b4a57613b4a615703565b9150915061440e8484815181106143fe576143fe615703565b6020026020010151838388614879565b8461441a6001866156ea565b8151811061442a5761442a615703565b602002602001018181525050505080806144439061592f565b9150506143a2565b60005b6001835161445c91906156ea565b811015613a1a5760008084838151811061447857614478615703565b60200260200101518584600161448e91906157f0565b8151811061449e5761449e615703565b60200260200101519150915060006144b68383614b29565b50905060006144e67f00000000000000000000000000000000000000000000000000000000000000008585613bc6565b90506000806000808473ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015614539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061455d9190615982565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506000808773ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16146145bf5782846145c2565b83835b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a8116600483015292945090925083918c16906370a0823190602401602060405180830381865afa158015614636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061465a9190615756565b61466491906156ea565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152909650600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156146f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061471a9190615756565b11905061472987848484614120565b955050505050506000808573ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461476e57826000614772565b6000835b91509150600060028c5161478691906156ea565b8a10614792578a6147c3565b6147c37f0000000000000000000000000000000000000000000000000000000000000000898e61401a8e60026157f0565b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff87169063022c0d9f9061482b908690869086906024810161583b565b600060405180830381600087803b15801561484557600080fd5b505af1158015614859573d6000803e3d6000fd5b50505050505050505050505050808061487190615803565b91505061444e565b600080851161490a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f42696f4c6962726172793a20494e53554646494349454e545f4f55545055545f60448201527f414d4f554e54000000000000000000000000000000000000000000000000000060648201526084016105f2565b60008411801561491a5750600083115b6149a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f42696f4c6962726172793a20494e53554646494349454e545f4c49515549444960448201527f545900000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b60006149b286866158b7565b6149be906127106158b7565b90506000836149cf576126de6149d3565b6126f75b61ffff166149e188876156ea565b6149eb91906158b7565b90506149f781836158f4565b614a029060016157f0565b979650505050505050565b6000808411614a78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f42696f4c6962726172793a20494e53554646494349454e545f414d4f554e540060448201526064016105f2565b600083118015614a885750600082115b614b14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f42696f4c6962726172793a20494e53554646494349454e545f4c49515549444960448201527f545900000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b82614b1f83866158b7565b61071e91906158f4565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603614bc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f42696f4c6962726172793a204944454e544943414c5f4144445245535345530060448201526064016105f2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610614bfb578284614bfe565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff8216614c80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f42696f4c6962726172793a205a45524f5f41444452455353000000000000000060448201526064016105f2565b9250929050565b6040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152600091829182917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015614d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d4891906159d2565b73ffffffffffffffffffffffffffffffffffffffff1603614e1f576040517fc9c6539600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015288811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303816000875af1158015614df9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614e1d91906159d2565b505b600080614e4d7f00000000000000000000000000000000000000000000000000000000000000008b8b614f98565b91509150816000148015614e5f575080155b15614e6f57879350869250614f8b565b6000614e7c898484614a0d565b9050878111614efa5785811015614eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f425f414d4f554e5460448201526064016105f2565b889450925082614f89565b6000614f07898486614a0d565b905089811115614f1957614f196150a3565b87811015614f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f415f414d4f554e5460448201526064016105f2565b94508793505b505b5050965096945050505050565b6000806000614fa78585614b29565b509050614fb5868686613bc6565b50600080614fc4888888613bc6565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561500e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906150329190615982565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614615091578082615094565b81815b90999098509650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146150f457600080fd5b50565b8035615102816150d2565b919050565b60008060008060008060c0878903121561512057600080fd5b863561512b816150d2565b95506020870135945060408701359350606087013592506080870135615150816150d2565b8092505060a087013590509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80151581146150f457600080fd5b803561510281615194565b6000806000606084860312156151c257600080fd5b8335925060208085013567ffffffffffffffff808211156151e257600080fd5b818701915087601f8301126151f657600080fd5b81358181111561520857615208615165565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561524b5761524b615165565b60405291825284820192508381018501918a83111561526957600080fd5b938501935b8285101561528e5761527f856150f7565b8452938501939285019261526e565b8097505050505050506152a3604085016151a2565b90509250925092565b6020808252825182820181905260009190848201906040850190845b818110156152e4578351835292840192918401916001016152c8565b50909695505050505050565b60008083601f84011261530257600080fd5b50813567ffffffffffffffff81111561531a57600080fd5b6020830191508360208260051b8501011115614c8057600080fd5b60008060008060008060a0878903121561534e57600080fd5b8635955060208701359450604087013567ffffffffffffffff81111561537357600080fd5b61537f89828a016152f0565b9095509350506060870135615393816150d2565b80925050608087013590509295509295509295565b803560ff8116811461510257600080fd5b60008060008060008060008060008060006101608c8e0312156153db57600080fd5b8b356153e6816150d2565b9a5060208c01356153f6816150d2565b995060408c0135985060608c0135975060808c0135965060a08c013561541b816150d2565b955060c08c0135945060e08c013561543281615194565b93506154416101008d016153a8565b92506101208c013591506101408c013590509295989b509295989b9093969950565b6000806000806080858703121561547957600080fd5b843593506020850135925060408501359150606085013561549981615194565b939692955090935050565b6000806000806000806000806000806101408b8d0312156154c457600080fd5b8a356154cf816150d2565b995060208b0135985060408b0135975060608b0135965060808b01356154f4816150d2565b955060a08b0135945060c08b013561550b81615194565b935061551960e08c016153a8565b92506101008b013591506101208b013590509295989b9194979a5092959850565b60008060008060006080868803121561555257600080fd5b85359450602086013567ffffffffffffffff81111561557057600080fd5b61557c888289016152f0565b9095509350506040860135615590816150d2565b949793965091946060013592915050565b6000806000606084860312156155b657600080fd5b505081359360208301359350604090920135919050565b600080600080600080600060e0888a0312156155e857600080fd5b87356155f3816150d2565b96506020880135615603816150d2565b955060408801359450606088013593506080880135925060a0880135615628816150d2565b8092505060c0880135905092959891949750929550565b600080600080600080600080610100898b03121561565c57600080fd5b8835615667816150d2565b97506020890135615677816150d2565b965060408901359550606089013594506080890135935060a0890135925060c08901356156a3816150d2565b8092505060e089013590509295985092959890939650565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156156fd576156fd6156bb565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561574457600080fd5b813561574f816150d2565b9392505050565b60006020828403121561576857600080fd5b5051919050565b60006020828403121561578157600080fd5b815161574f81615194565b6000806040838503121561579f57600080fd5b505080516020909101519092909150565b60005b838110156157cb5781810151838201526020016157b3565b50506000910152565b600082516157e68184602087016157b0565b9190910192915050565b808201808211156156fd576156fd6156bb565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615834576158346156bb565b5060010190565b84815283602082015273ffffffffffffffffffffffffffffffffffffffff8316604082015260806060820152600082518060808401526158828160a08501602087016157b0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160a00195945050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156158ef576158ef6156bb565b500290565b60008261592a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008161593e5761593e6156bb565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80516dffffffffffffffffffffffffffff8116811461510257600080fd5b60008060006060848603121561599757600080fd5b6159a084615964565b92506159ae60208501615964565b9150604084015163ffffffff811681146159c757600080fd5b809150509250925092565b6000602082840312156159e457600080fd5b815161574f816150d256fea2646970667358221220f37642688b9bcb6b4eca87c16701ac98ee94b7e424fe6fc6a3a11cd64c001b9c64736f6c63430008100033000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d

Deployed Bytecode

0x60806040526004361061019a5760003560e01c80638803dbee116100e1578063baa2abde1161008a578063e8e3370011610064578063e8e33700146104f3578063f27999731461052e578063f305d71914610562578063fb3bdb411461057557600080fd5b8063baa2abde1461047f578063c45a01551461049f578063ded9382a146104d357600080fd5b8063ad615dec116100bb578063ad615dec1461042c578063af2979eb1461044c578063b6f9de951461046c57600080fd5b80638803dbee14610393578063a5ff0d12146103b3578063ad5c4648146103d357600080fd5b80634a25d94a11610143578063684ab99b1161011d578063684ab99b14610340578063791ac947146103605780637ff36ab51461038057600080fd5b80634a25d94a146102e05780635b0d5984146103005780635c11d7951461032057600080fd5b80632195995c116101745780632195995c146102725780632e08a6ee1461029257806338ed1739146102c057600080fd5b806302751cec146101eb57806312a1c5f11461022557806318cbafe51461025257600080fd5b366101e6573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216146101e4576101e46150a3565b005b600080fd5b3480156101f757600080fd5b5061020b610206366004615107565b610588565b604080519283526020830191909152015b60405180910390f35b34801561023157600080fd5b506102456102403660046151ad565b6106f0565b60405161021c91906152ac565b34801561025e57600080fd5b5061024561026d366004615335565b610726565b34801561027e57600080fd5b5061020b61028d3660046153b9565b610c39565b34801561029e57600080fd5b506102b26102ad366004615463565b610d70565b60405190815260200161021c565b3480156102cc57600080fd5b506102456102db366004615335565b610d87565b3480156102ec57600080fd5b506102456102fb366004615335565b611017565b34801561030c57600080fd5b506102b261031b3660046154a4565b61132b565b34801561032c57600080fd5b506101e461033b366004615335565b611476565b34801561034c57600080fd5b5061024561035b3660046151ad565b6117df565b34801561036c57600080fd5b506101e461037b366004615335565b61180d565b61024561038e36600461553a565b611b9e565b34801561039f57600080fd5b506102456103ae366004615335565b6120dd565b3480156103bf57600080fd5b506102b26103ce366004615463565b61230c565b3480156103df57600080fd5b506104077f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b34801561043857600080fd5b506102b26104473660046155a1565b61231a565b34801561045857600080fd5b506102b2610467366004615107565b612327565b6101e461047a36600461553a565b612517565b34801561048b57600080fd5b5061020b61049a3660046155cd565b612987565b3480156104ab57600080fd5b506104077f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca81565b3480156104df57600080fd5b5061020b6104ee3660046154a4565b612c93565b3480156104ff57600080fd5b5061051361050e36600461563f565b612de4565b6040805193845260208401929092529082015260600161021c565b34801561053a57600080fd5b506104077f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d81565b610513610570366004615107565b612f52565b61024561058336600461553a565b613254565b60008082428110156105fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064015b60405180910390fd5b61062a897f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8a8a308a612987565b909350915061063a8986856137a0565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b505050506106e48583613910565b50965096945050505050565b606061071e7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca858585613a1f565b949350505050565b60608142811015610793576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21686866107d76001826156ea565b8181106107e6576107e6615703565b90506020020160208101906107fb9190615732565b73ffffffffffffffffffffffffffffffffffffffff1614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa158015610907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092b9190615756565b11905061098e7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8a898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250613a1f915050565b92508783600185516109a091906156ea565b815181106109b0576109b0615703565b60200260200101511015610a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b610b0b87876000818110610a5c57610a5c615703565b9050602002016020810190610a719190615732565b33610aeb7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8b8b6000818110610aa957610aa9615703565b9050602002016020810190610abe9190615732565b8c8c6001818110610ad157610ad1615703565b9050602002016020810190610ae69190615732565b613bc6565b86600081518110610afe57610afe615703565b6020026020010151613d53565b610b4a83888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613ef1915050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d8460018651610b9591906156ea565b81518110610ba557610ba5615703565b60200260200101516040518263ffffffff1660e01b8152600401610bcb91815260200190565b600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b50505050610c2d858460018651610c1091906156ea565b81518110610c2057610c20615703565b6020026020010151613910565b50509695505050505050565b6000806000610c697f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8f8f613bc6565b9050600087610c78578c610c9a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015610d2f57600080fd5b505af1158015610d43573d6000803e3d6000fd5b50505050610d568f8f8f8f8f8f8f612987565b809450819550505050509b509b9950505050505050505050565b6000610d7e85858585614120565b95945050505050565b60608142811015610df4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa158015610e83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea79190615756565b119050610f0a7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8a898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250613a1f915050565b9250878360018551610f1c91906156ea565b81518110610f2c57610f2c615703565b60200260200101511015610fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b610fd887876000818110610a5c57610a5c615703565b610c2d838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613ef1915050565b60608142811015611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21686866110c86001826156ea565b8181106110d7576110d7615703565b90506020020160208101906110ec9190615732565b73ffffffffffffffffffffffffffffffffffffffff1614611169576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa1580156111f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121c9190615756565b11905061127f7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8a8989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792506142af915050565b9250878360008151811061129557611295615703565b60200260200101511115610a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f42696f526f757465723a204558434553534956455f494e5055545f414d4f554e60448201527f540000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6000806113797f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2613bc6565b9050600086611388578b6113aa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018a905260ff8816608482015260a4810187905260c4810186905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b15801561143f57600080fd5b505af1158015611453573d6000803e3d6000fd5b505050506114658d8d8d8d8d8d612327565b9d9c50505050505050505050505050565b80428110156114e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b611572858560008181106114f7576114f7615703565b905060200201602081019061150c9190615732565b3361156c7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8989600081811061154457611544615703565b90506020020160208101906115599190615732565b8a8a6001818110610ad157610ad1615703565b8a613d53565b600085856115816001826156ea565b81811061159057611590615703565b90506020020160208101906115a59190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015291909116906370a0823190602401602060405180830381865afa158015611613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116379190615756565b905061167786868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525088925061444b915050565b868187876116866001826156ea565b81811061169557611695615703565b90506020020160208101906116aa9190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015291909116906370a08231906024015b602060405180830381865afa158015611719573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173d9190615756565b61174791906156ea565b10156117d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b5050505050505050565b606061071e7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8585856142af565b8042811015611878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21685856118bc6001826156ea565b8181106118cb576118cb615703565b90506020020160208101906118e09190615732565b73ffffffffffffffffffffffffffffffffffffffff161461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b611973858560008181106114f7576114f7615703565b6119b185858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525030925061444b915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611a3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a629190615756565b905086811015611af4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015611b7c57600080fd5b505af1158015611b90573d6000803e3d6000fd5b505050506117d58482613910565b60608142811015611c0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1686866000818110611c5557611c55615703565b9050602002016020810190611c6a9190615732565b73ffffffffffffffffffffffffffffffffffffffff1614611ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa158015611d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9a9190615756565b119050611dfd7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca34898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250879250613a1f915050565b9250878360018551611e0f91906156ea565b81518110611e1f57611e1f615703565b60200260200101511015611eb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f526f757465723a20494e53554646494349454e545f4f55545055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db084600081518110611f0457611f04615703565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f3757600080fd5b505af1158015611f4b573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb611feb7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8a8a6000818110611fc357611fc3615703565b9050602002016020810190611fd89190615732565b8b8b6001818110610ad157610ad1615703565b85600081518110611ffe57611ffe615703565b60200260200101516040518363ffffffff1660e01b815260040161204492919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015612063573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612087919061576f565b612093576120936150a3565b6120d2838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613ef1915050565b505095945050505050565b6060814281101561214a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa1580156121d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fd9190615756565b1190506122607f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8a8989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792506142af915050565b9250878360008151811061227657612276615703565b60200260200101511115610fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f42696f526f757465723a204558434553534956455f494e5055545f414d4f554e60448201527f540000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6000610d7e85858585614879565b600061071e848484614a0d565b60008142811015612394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6123c3887f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28989893089612987565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290935061246291508990869073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245d9190615756565b6137a0565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156124ea57600080fd5b505af11580156124fe573d6000803e3d6000fd5b5050505061250c8483613910565b509695505050505050565b8042811015612582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16858560008181106125cc576125cc615703565b90506020020160208101906125e19190615732565b73ffffffffffffffffffffffffffffffffffffffff161461265e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b60003490507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156126cb57600080fd5b505af11580156126df573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6127577f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8989600081811061154457611544615703565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af11580156127c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ed919061576f565b6127f9576127f96150a3565b600086866128086001826156ea565b81811061281757612817615703565b905060200201602081019061282c9190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291909116906370a0823190602401602060405180830381865afa15801561289a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128be9190615756565b90506128fe87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525089925061444b915050565b8781888861290d6001826156ea565b81811061291c5761291c615703565b90506020020160208101906129319190615732565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015291909116906370a08231906024016116fc565b60008082428110156129f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b6000612a227f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8c8c613bc6565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af1158015612a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac2919061576f565b506040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015612b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b59919061578c565b915091506000612b698e8e614b29565b5090508073ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff1614612ba6578183612ba9565b82825b90975095508a871015612c18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f415f414d4f554e5460448201526064016105f2565b89861015612c82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f425f414d4f554e5460448201526064016105f2565b505050505097509795505050505050565b6000806000612ce37f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2613bc6565b9050600087612cf2578c612d14565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101829052606481018b905260ff8916608482015260a4810188905260c4810187905290915073ffffffffffffffffffffffffffffffffffffffff83169063d505accf9060e401600060405180830381600087803b158015612da957600080fd5b505af1158015612dbd573d6000803e3d6000fd5b50505050612dcf8e8e8e8e8e8e610588565b909f909e509c50505050505050505050505050565b60008060008342811015612e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b612e628c8c8c8c8c8c614c87565b90945092506000612e947f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8e8e613bc6565b9050612ea28d338388613d53565b612eae8c338387613d53565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af1158015612f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f409190615756565b92505050985098509895505050505050565b60008060008342811015612fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b612ff08a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b348c8c614c87565b909450925060006130427f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2613bc6565b90506130508b338388613d53565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130b857600080fd5b505af11580156130cc573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018990527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216935063a9059cbb925060440190506020604051808303816000875af1158015613167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318b919061576f565b613197576131976150a3565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152821690636a627842906024016020604051808303816000875af1158015613205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132299190615756565b925083341115613246576132463361324186346156ea565b613910565b505096509650969350505050565b606081428110156132c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42696f526f757465723a2045585049524544000000000000000000000000000060448201526064016105f2565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168686600081811061330b5761330b615703565b90506020020160208101906133209190615732565b73ffffffffffffffffffffffffffffffffffffffff161461339d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f42696f526f757465723a20494e56414c49445f5041544800000000000000000060448201526064016105f2565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa15801561342c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134509190615756565b1190506134b37f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca898989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792506142af915050565b925034836000815181106134c9576134c9615703565b6020026020010151111561355f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f42696f526f757465723a204558434553534956455f494e5055545f414d4f554e60448201527f540000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0846000815181106135ae576135ae615703565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156135e157600080fd5b505af11580156135f5573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61366d7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8a8a6000818110611fc357611fc3615703565b8560008151811061368057613680615703565b60200260200101516040518363ffffffff1660e01b81526004016136c692919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af11580156136e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613709919061576f565b613715576137156150a3565b613754838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613ef1915050565b8260008151811061376757613767615703565b60200260200101513411156120d2576120d2338460008151811061378d5761378d615703565b60200260200101513461324191906156ea565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161383791906157d4565b6000604051808303816000865af19150503d8060008114613874576040519150601f19603f3d011682016040523d82523d6000602084013e613879565b606091505b50915091508180156138a35750805115806138a35750808060200190518101906138a3919061576f565b613909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016105f2565b5050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161394791906157d4565b60006040518083038185875af1925050503d8060008114613984576040519150601f19603f3d011682016040523d82523d6000602084013e613989565b606091505b5050905080613a1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c4544000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b505050565b6060600283511015613a8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f42696f4c6962726172793a20494e56414c49445f50415448000000000000000060448201526064016105f2565b825167ffffffffffffffff811115613aa757613aa7615165565b604051908082528060200260200182016040528015613ad0578160200160208202803683370190505b5090508381600081518110613ae757613ae7615703565b60200260200101818152505060005b60018451613b0491906156ea565b811015613bbd57600080613b5788878581518110613b2457613b24615703565b602002602001015188866001613b3a91906157f0565b81518110613b4a57613b4a615703565b6020026020010151614f98565b91509150613b80848481518110613b7057613b70615703565b6020026020010151838388614120565b84613b8c8560016157f0565b81518110613b9c57613b9c615703565b60200260200101818152505050508080613bb590615803565b915050613af6565b50949350505050565b6000806000613bd58585614b29565b9150915060008673ffffffffffffffffffffffffffffffffffffffff16635855a25a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4a9190615756565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086811b8216602084015285901b16603482015290915087906048016040516020818303038152906040528051906020012082604051602001613d12939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120979650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691613df291906157d4565b6000604051808303816000865af19150503d8060008114613e2f576040519150601f19603f3d011682016040523d82523d6000602084013e613e34565b606091505b5091509150818015613e5e575080511580613e5e575080806020019051810190613e5e919061576f565b613ee9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160448201527f494c45440000000000000000000000000000000000000000000000000000000060648201526084016105f2565b505050505050565b60005b60018351613f0291906156ea565b81101561411a57600080848381518110613f1e57613f1e615703565b602002602001015185846001613f3491906157f0565b81518110613f4457613f44615703565b6020026020010151915091506000613f5c8383614b29565b509050600087613f6d8660016157f0565b81518110613f7d57613f7d615703565b602002602001015190506000808373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614613fc557826000613fc9565b6000835b91509150600060028a51613fdd91906156ea565b8810613fe95788614037565b6140377f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca878c61401a8c60026157f0565b8151811061402a5761402a615703565b6020026020010151613bc6565b90506140647f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8888613bc6565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f84848460006040519080825280601f01601f1916602001820160405280156140ae576020820181803683370190505b506040518563ffffffff1660e01b81526004016140ce949392919061583b565b600060405180830381600087803b1580156140e857600080fd5b505af11580156140fc573d6000803e3d6000fd5b5050505050505050505050808061411290615803565b915050613ef4565b50505050565b60008085116141b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f42696f4c6962726172793a20494e53554646494349454e545f494e5055545f4160448201527f4d4f554e5400000000000000000000000000000000000000000000000000000060648201526084016105f2565b6000841180156141c15750600083115b61424d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f42696f4c6962726172793a20494e53554646494349454e545f4c49515549444960448201527f545900000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b60008261425c576126de614260565b6126f75b61426e9061ffff16876158b7565b9050600061427c85836158b7565b905060008261428d886127106158b7565b61429791906157f0565b90506142a381836158f4565b98975050505050505050565b606060028351101561431d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f42696f4c6962726172793a20494e56414c49445f50415448000000000000000060448201526064016105f2565b825167ffffffffffffffff81111561433757614337615165565b604051908082528060200260200182016040528015614360578160200160208202803683370190505b50905083816001835161437391906156ea565b8151811061438357614383615703565b60200260200101818152505060006001845161439f91906156ea565b90505b8015613bbd576000806143e588876143bb6001876156ea565b815181106143cb576143cb615703565b6020026020010151888681518110613b4a57613b4a615703565b9150915061440e8484815181106143fe576143fe615703565b6020026020010151838388614879565b8461441a6001866156ea565b8151811061442a5761442a615703565b602002602001018181525050505080806144439061592f565b9150506143a2565b60005b6001835161445c91906156ea565b811015613a1a5760008084838151811061447857614478615703565b60200260200101518584600161448e91906157f0565b8151811061449e5761449e615703565b60200260200101519150915060006144b68383614b29565b50905060006144e67f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8585613bc6565b90506000806000808473ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015614539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061455d9190615982565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506000808773ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16146145bf5782846145c2565b83835b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a8116600483015292945090925083918c16906370a0823190602401602060405180830381865afa158015614636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061465a9190615756565b61466491906156ea565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152909650600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d16906370a0823190602401602060405180830381865afa1580156146f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061471a9190615756565b11905061472987848484614120565b955050505050506000808573ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461476e57826000614772565b6000835b91509150600060028c5161478691906156ea565b8a10614792578a6147c3565b6147c37f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca898e61401a8e60026157f0565b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff87169063022c0d9f9061482b908690869086906024810161583b565b600060405180830381600087803b15801561484557600080fd5b505af1158015614859573d6000803e3d6000fd5b50505050505050505050505050808061487190615803565b91505061444e565b600080851161490a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f42696f4c6962726172793a20494e53554646494349454e545f4f55545055545f60448201527f414d4f554e54000000000000000000000000000000000000000000000000000060648201526084016105f2565b60008411801561491a5750600083115b6149a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f42696f4c6962726172793a20494e53554646494349454e545f4c49515549444960448201527f545900000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b60006149b286866158b7565b6149be906127106158b7565b90506000836149cf576126de6149d3565b6126f75b61ffff166149e188876156ea565b6149eb91906158b7565b90506149f781836158f4565b614a029060016157f0565b979650505050505050565b6000808411614a78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f42696f4c6962726172793a20494e53554646494349454e545f414d4f554e540060448201526064016105f2565b600083118015614a885750600082115b614b14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f42696f4c6962726172793a20494e53554646494349454e545f4c49515549444960448201527f545900000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b82614b1f83866158b7565b61071e91906158f4565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603614bc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f42696f4c6962726172793a204944454e544943414c5f4144445245535345530060448201526064016105f2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610614bfb578284614bfe565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff8216614c80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f42696f4c6962726172793a205a45524f5f41444452455353000000000000000060448201526064016105f2565b9250929050565b6040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152600091829182917f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca9091169063e6a4390590604401602060405180830381865afa158015614d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d4891906159d2565b73ffffffffffffffffffffffffffffffffffffffff1603614e1f576040517fc9c6539600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff898116600483015288811660248301527f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca169063c9c65396906044016020604051808303816000875af1158015614df9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614e1d91906159d2565b505b600080614e4d7f000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca8b8b614f98565b91509150816000148015614e5f575080155b15614e6f57879350869250614f8b565b6000614e7c898484614a0d565b9050878111614efa5785811015614eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f425f414d4f554e5460448201526064016105f2565b889450925082614f89565b6000614f07898486614a0d565b905089811115614f1957614f196150a3565b87811015614f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f42696f526f757465723a20494e53554646494349454e545f415f414d4f554e5460448201526064016105f2565b94508793505b505b5050965096945050505050565b6000806000614fa78585614b29565b509050614fb5868686613bc6565b50600080614fc4888888613bc6565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561500e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906150329190615982565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614615091578082615094565b81815b90999098509650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146150f457600080fd5b50565b8035615102816150d2565b919050565b60008060008060008060c0878903121561512057600080fd5b863561512b816150d2565b95506020870135945060408701359350606087013592506080870135615150816150d2565b8092505060a087013590509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80151581146150f457600080fd5b803561510281615194565b6000806000606084860312156151c257600080fd5b8335925060208085013567ffffffffffffffff808211156151e257600080fd5b818701915087601f8301126151f657600080fd5b81358181111561520857615208615165565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561524b5761524b615165565b60405291825284820192508381018501918a83111561526957600080fd5b938501935b8285101561528e5761527f856150f7565b8452938501939285019261526e565b8097505050505050506152a3604085016151a2565b90509250925092565b6020808252825182820181905260009190848201906040850190845b818110156152e4578351835292840192918401916001016152c8565b50909695505050505050565b60008083601f84011261530257600080fd5b50813567ffffffffffffffff81111561531a57600080fd5b6020830191508360208260051b8501011115614c8057600080fd5b60008060008060008060a0878903121561534e57600080fd5b8635955060208701359450604087013567ffffffffffffffff81111561537357600080fd5b61537f89828a016152f0565b9095509350506060870135615393816150d2565b80925050608087013590509295509295509295565b803560ff8116811461510257600080fd5b60008060008060008060008060008060006101608c8e0312156153db57600080fd5b8b356153e6816150d2565b9a5060208c01356153f6816150d2565b995060408c0135985060608c0135975060808c0135965060a08c013561541b816150d2565b955060c08c0135945060e08c013561543281615194565b93506154416101008d016153a8565b92506101208c013591506101408c013590509295989b509295989b9093969950565b6000806000806080858703121561547957600080fd5b843593506020850135925060408501359150606085013561549981615194565b939692955090935050565b6000806000806000806000806000806101408b8d0312156154c457600080fd5b8a356154cf816150d2565b995060208b0135985060408b0135975060608b0135965060808b01356154f4816150d2565b955060a08b0135945060c08b013561550b81615194565b935061551960e08c016153a8565b92506101008b013591506101208b013590509295989b9194979a5092959850565b60008060008060006080868803121561555257600080fd5b85359450602086013567ffffffffffffffff81111561557057600080fd5b61557c888289016152f0565b9095509350506040860135615590816150d2565b949793965091946060013592915050565b6000806000606084860312156155b657600080fd5b505081359360208301359350604090920135919050565b600080600080600080600060e0888a0312156155e857600080fd5b87356155f3816150d2565b96506020880135615603816150d2565b955060408801359450606088013593506080880135925060a0880135615628816150d2565b8092505060c0880135905092959891949750929550565b600080600080600080600080610100898b03121561565c57600080fd5b8835615667816150d2565b97506020890135615677816150d2565b965060408901359550606089013594506080890135935060a0890135925060c08901356156a3816150d2565b8092505060e089013590509295985092959890939650565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156156fd576156fd6156bb565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561574457600080fd5b813561574f816150d2565b9392505050565b60006020828403121561576857600080fd5b5051919050565b60006020828403121561578157600080fd5b815161574f81615194565b6000806040838503121561579f57600080fd5b505080516020909101519092909150565b60005b838110156157cb5781810151838201526020016157b3565b50506000910152565b600082516157e68184602087016157b0565b9190910192915050565b808201808211156156fd576156fd6156bb565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615834576158346156bb565b5060010190565b84815283602082015273ffffffffffffffffffffffffffffffffffffffff8316604082015260806060820152600082518060808401526158828160a08501602087016157b0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160a00195945050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156158ef576158ef6156bb565b500290565b60008261592a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008161593e5761593e6156bb565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80516dffffffffffffffffffffffffffff8116811461510257600080fd5b60008060006060848603121561599757600080fd5b6159a084615964565b92506159ae60208501615964565b9150604084015163ffffffff811681146159c757600080fd5b809150509250925092565b6000602082840312156159e457600080fd5b815161574f816150d256fea2646970667358221220f37642688b9bcb6b4eca87c16701ac98ee94b7e424fe6fc6a3a11cd64c001b9c64736f6c63430008100033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d

-----Decoded View---------------
Arg [0] : _factory (address): 0xa407F4Bac1D84eEc6468661b7d3Bbf839f45c2ca
Arg [1] : _WETH (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _BIONIC (address): 0x0e5ec8A3165644d8533F9e5aC7e0f682f8FB078D

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000a407f4bac1d84eec6468661b7d3bbf839f45c2ca
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 0000000000000000000000000e5ec8a3165644d8533f9e5ac7e0f682f8fb078d


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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.