ETH Price: $2,950.13 (-2.11%)

Contract

0x80e38291e06339d10AAB483C65695D004dBD5C69

Overview

ETH Balance

Linea Mainnet LogoLinea Mainnet LogoLinea Mainnet Logo0.000090745624740967 ETH

ETH Value

$0.27 (@ $2,950.13/ETH)

More Info

Private Name Tags

Transaction Hash
Block
From
To
0x032088d3cae5fe5f7771f71436295173f29bcfb914a3fe02231059cfb100f671 -(pending)2026-01-16 7:09:0013 days ago1768547340IN
SyncSwap: Router
0.0000102456 ETH(Pending)(Pending)
0x4b3f49900db2b3e588946bf74174da3869193df7e88d3fb5177b05e7d4fdc6de -(pending)2026-01-16 7:08:5913 days ago1768547339IN
SyncSwap: Router
0 ETH(Pending)(Pending)
Swap284300012026-01-29 8:35:0228 mins ago1769675702IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284298862026-01-29 8:29:1834 mins ago1769675358IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284298362026-01-29 8:27:1636 mins ago1769675236IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284294872026-01-29 8:11:0052 mins ago1769674260IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284290432026-01-29 7:49:461 hr ago1769672986IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284249642026-01-29 4:53:464 hrs ago1769662426IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284242582026-01-29 4:22:284 hrs ago1769660548IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284231412026-01-29 3:31:465 hrs ago1769657506IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284230072026-01-29 3:25:185 hrs ago1769657118IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284225472026-01-29 3:05:345 hrs ago1769655934IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284223252026-01-29 2:56:266 hrs ago1769655386IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284221772026-01-29 2:49:446 hrs ago1769654984IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284221342026-01-29 2:48:026 hrs ago1769654882IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284219712026-01-29 2:41:246 hrs ago1769654484IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284217562026-01-29 2:32:146 hrs ago1769653934IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284217482026-01-29 2:31:586 hrs ago1769653918IN
SyncSwap: Router
0.05093194 ETH0.000008570.05429221
Swap284217482026-01-29 2:31:586 hrs ago1769653918IN
SyncSwap: Router
0.03003057 ETH0.000012630.08
Swap284217472026-01-29 2:31:566 hrs ago1769653916IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284217452026-01-29 2:31:526 hrs ago1769653912IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284204652026-01-29 1:37:367 hrs ago1769650656IN
SyncSwap: Router
0.004214 ETH0.000013190.07857
Swap284201762026-01-29 1:25:567 hrs ago1769649956IN
SyncSwap: Router
0 ETH0.000007150.04004862
Swap284193442026-01-29 0:48:328 hrs ago1769647712IN
SyncSwap: Router
0 ETH0.000007370.04004862
Swap284192542026-01-29 0:45:108 hrs ago1769647510IN
SyncSwap: Router
0 ETH0.000007150.04004862
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
284300012026-01-29 8:35:0228 mins ago1769675702
SyncSwap: Router
0 ETH
284300012026-01-29 8:35:0228 mins ago1769675702
SyncSwap: Router
0 ETH
284300012026-01-29 8:35:0228 mins ago1769675702
SyncSwap: Router
0 ETH
284298862026-01-29 8:29:1834 mins ago1769675358
SyncSwap: Router
0 ETH
284298862026-01-29 8:29:1834 mins ago1769675358
SyncSwap: Router
0 ETH
284298862026-01-29 8:29:1834 mins ago1769675358
SyncSwap: Router
0 ETH
284298362026-01-29 8:27:1636 mins ago1769675236
SyncSwap: Router
0 ETH
284298362026-01-29 8:27:1636 mins ago1769675236
SyncSwap: Router
0 ETH
284298362026-01-29 8:27:1636 mins ago1769675236
SyncSwap: Router
0 ETH
284297862026-01-29 8:25:1038 mins ago1769675110
SyncSwap: Router
0 ETH
284297862026-01-29 8:25:1038 mins ago1769675110
SyncSwap: Router
0 ETH
284297862026-01-29 8:25:1038 mins ago1769675110
SyncSwap: Router
0 ETH
284297862026-01-29 8:25:1038 mins ago1769675110
SyncSwap: Router
0 ETH
284294872026-01-29 8:11:0052 mins ago1769674260
SyncSwap: Router
0 ETH
284294872026-01-29 8:11:0052 mins ago1769674260
SyncSwap: Router
0 ETH
284294872026-01-29 8:11:0052 mins ago1769674260
SyncSwap: Router
0 ETH
284290432026-01-29 7:49:461 hr ago1769672986
SyncSwap: Router
0 ETH
284290432026-01-29 7:49:461 hr ago1769672986
SyncSwap: Router
0 ETH
284290432026-01-29 7:49:461 hr ago1769672986
SyncSwap: Router
0 ETH
284281152026-01-29 7:11:381 hr ago1769670698
SyncSwap: Router
0 ETH
284281152026-01-29 7:11:381 hr ago1769670698
SyncSwap: Router
0 ETH
284281152026-01-29 7:11:381 hr ago1769670698
SyncSwap: Router
0 ETH
284281152026-01-29 7:11:381 hr ago1769670698
SyncSwap: Router
0 ETH
284268102026-01-29 6:18:002 hrs ago1769667480
SyncSwap: Router
0 ETH
284268102026-01-29 6:18:002 hrs ago1769667480
SyncSwap: Router
0 ETH
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SyncSwapRouter

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity ^0.8.0;

import "./interfaces/IWETH.sol";
import "./interfaces/IRouter.sol";
import "./interfaces/IStakingPool.sol";
import "./interfaces/vault/IVault.sol";
import "./interfaces/pool/IPool.sol";
import "./interfaces/pool/IBasePool.sol";
import "./interfaces/token/IERC20Permit.sol";
import "./interfaces/factory/IPoolFactory.sol";

import "./libraries/TransferHelper.sol";

import "./abstract/SelfPermit.sol";
import "./abstract/Multicall.sol";

error NotEnoughLiquidityMinted();
error TooLittleReceived();
error Expired();

/// @notice The router is a universal interface for users to access
/// functions across different protocol parts in one place.
///
/// It handles the allowances and transfers of tokens, and
/// allows chained swaps/operations across multiple pools, with
/// additional features like slippage protection and permit support.
///
contract SyncSwapRouter is IRouter, SelfPermit, Multicall {

    struct TokenInput {
        address token;
        uint amount;
    }

    address public immutable vault;
    address public immutable wETH;
    address private constant NATIVE_ETH = address(0);

    mapping(address => mapping(address => bool)) public isPoolEntered;
    mapping(address => address[]) public enteredPools;

    modifier ensure(uint deadline) {
        // solhint-disable-next-line not-rely-on-time
        if (block.timestamp > deadline) {
            revert Expired();
        }
        _;
    }

    constructor(address _vault, address _wETH) {
        vault = _vault;
        wETH = _wETH;
    }

    function enteredPoolsLength(address account) external view returns (uint) {
        return enteredPools[account].length;
    }

    // Add Liquidity
    function _transferFromSender(address token, address to, uint amount) private {
        if (token == NATIVE_ETH) {
            // Deposit ETH to the vault.
            IVault(vault).deposit{value: amount}(token, to);
        } else {
            // Transfer tokens to the vault.
            TransferHelper.safeTransferFrom(token, msg.sender, vault, amount);

            // Notify the vault to deposit.
            IVault(vault).deposit(token, to);
        }
    }

    function _transferAndAddLiquidity(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData
    ) private returns (uint liquidity) {
        // Send all input tokens to the pool.
        uint n = inputs.length;

        TokenInput memory input;

        for (uint i; i < n; ) {
            input = inputs[i];

            _transferFromSender(input.token, pool, input.amount);

            unchecked {
                ++i;
            }
        }

        liquidity = IPool(pool).mint(data, msg.sender, callback, callbackData);

        if (liquidity < minLiquidity) {
            revert NotEnoughLiquidityMinted();
        }
    }

    function _markPoolEntered(address pool) private {
        if (!isPoolEntered[pool][msg.sender]) {
            isPoolEntered[pool][msg.sender] = true;
            enteredPools[msg.sender].push(pool);
        }
    }

    function addLiquidity(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData
    ) external payable returns (uint liquidity) {
        liquidity = _transferAndAddLiquidity(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData
        );
    }

    function addLiquidity2(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData
    ) external payable returns (uint liquidity) {
        liquidity = _transferAndAddLiquidity(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData
        );

        _markPoolEntered(pool);
    }

    function addLiquidityWithPermit(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData,
        SplitPermitParams[] memory permits
    ) public payable returns (uint liquidity) {
        // Approve all tokens via permit.
        uint n = permits.length;

        SplitPermitParams memory params;

        for (uint i; i < n; ) {
            params = permits[i];

            IERC20Permit(params.token).permit(
                msg.sender,
                address(this),
                params.approveAmount,
                params.deadline,
                params.v,
                params.r,
                params.s
            );

            unchecked {
                ++i;
            }
        }

        liquidity = _transferAndAddLiquidity(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData
        );
    }

    function addLiquidityWithPermit2(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData,
        SplitPermitParams[] memory permits
    ) public payable returns (uint liquidity) {
        liquidity = addLiquidityWithPermit(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData,
            permits
        );

        _markPoolEntered(pool);
    }

    // Burn Liquidity
    function _transferAndBurnLiquidity(
        address pool,
        uint liquidity,
        bytes memory data,
        uint[] memory minAmounts,
        address callback,
        bytes calldata callbackData
    ) private returns (IPool.TokenAmount[] memory amounts) {
        IBasePool(pool).transferFrom(msg.sender, pool, liquidity);

        amounts = IPool(pool).burn(data, msg.sender, callback, callbackData);

        uint n = amounts.length;

        for (uint i; i < n; ) {
            if (amounts[i].amount < minAmounts[i]) {
                revert TooLittleReceived();
            }

            unchecked {
                ++i;
            }
        }
    }

    function burnLiquidity(
        address pool,
        uint liquidity,
        bytes calldata data,
        uint[] calldata minAmounts,
        address callback,
        bytes calldata callbackData
    ) external returns (IPool.TokenAmount[] memory amounts) {
        amounts = _transferAndBurnLiquidity(
            pool,
            liquidity,
            data,
            minAmounts,
            callback,
            callbackData
        );
    }

    function burnLiquidityWithPermit(
        address pool,
        uint liquidity,
        bytes calldata data,
        uint[] calldata minAmounts,
        address callback,
        bytes calldata callbackData,
        ArrayPermitParams memory permit
    ) external returns (IPool.TokenAmount[] memory amounts) {
        // Approve liquidity via permit.
        IBasePool(pool).permit2(
            msg.sender,
            address(this),
            permit.approveAmount,
            permit.deadline,
            permit.signature
        );

        amounts = _transferAndBurnLiquidity(
            pool,
            liquidity,
            data,
            minAmounts,
            callback,
            callbackData
        );
    }

    // Burn Liquidity Single
    function _transferAndBurnLiquiditySingle(
        address pool,
        uint liquidity,
        bytes memory data,
        uint minAmount,
        address callback,
        bytes memory callbackData
    ) private returns (IPool.TokenAmount memory amountOut) {
        IBasePool(pool).transferFrom(msg.sender, pool, liquidity);

        amountOut = IPool(pool).burnSingle(data, msg.sender, callback, callbackData);

        if (amountOut.amount < minAmount) {
            revert TooLittleReceived();
        }
    }

    function burnLiquiditySingle(
        address pool,
        uint liquidity,
        bytes memory data,
        uint minAmount,
        address callback,
        bytes memory callbackData
    ) external returns (IPool.TokenAmount memory amountOut) {
        amountOut = _transferAndBurnLiquiditySingle(
            pool,
            liquidity,
            data,
            minAmount,
            callback,
            callbackData
        );
    }

    function burnLiquiditySingleWithPermit(
        address pool,
        uint liquidity,
        bytes memory data,
        uint minAmount,
        address callback,
        bytes memory callbackData,
        ArrayPermitParams calldata permit
    ) external returns (IPool.TokenAmount memory amountOut) {
        // Approve liquidity via permit.
        IBasePool(pool).permit2(
            msg.sender,
            address(this),
            permit.approveAmount,
            permit.deadline,
            permit.signature
        );

        amountOut = _transferAndBurnLiquiditySingle(
            pool,
            liquidity,
            data,
            minAmount,
            callback,
            callbackData
        );
    }

    // Swap
    function _swap(
        SwapPath[] memory paths,
        uint amountOutMin
    ) private returns (IPool.TokenAmount memory amountOut) {
        uint pathsLength = paths.length;

        SwapPath memory path;
        SwapStep memory step;
        IPool.TokenAmount memory tokenAmount;
        uint stepsLength;
        uint j;

        for (uint i; i < pathsLength; ) {
            path = paths[i];

            // Prefund the first step.
            step = path.steps[0];
            _transferFromSender(path.tokenIn, step.pool, path.amountIn);

            // Cache steps length.
            stepsLength = path.steps.length;

            for (j = 0; j < stepsLength; ) {
                if (j == stepsLength - 1) {
                    // Accumulate output amount at the last step.
                    tokenAmount = IBasePool(step.pool).swap(
                        step.data, msg.sender, step.callback, step.callbackData
                    );

                    amountOut.token = tokenAmount.token;
                    amountOut.amount += tokenAmount.amount;

                    break;
                } else {
                    // Swap and send tokens to the next step.
                    IBasePool(step.pool).swap(step.data, msg.sender, step.callback, step.callbackData);

                    // Cache the next step.
                    step = path.steps[j + 1];
                }

                unchecked {
                    ++j;
                }
            }

            unchecked {
                ++i;
            }
        }

        if (amountOut.amount < amountOutMin) {
            revert TooLittleReceived();
        }
    }

    function swap(
        SwapPath[] memory paths,
        uint amountOutMin,
        uint deadline
    ) external payable ensure(deadline) returns (IPool.TokenAmount memory amountOut) {
        amountOut = _swap(
            paths,
            amountOutMin
        );
    }

    function swapWithPermit(
        SwapPath[] memory paths,
        uint amountOutMin,
        uint deadline,
        SplitPermitParams calldata permit
    ) external payable ensure(deadline) returns (IPool.TokenAmount memory amountOut) {
        // Approve input tokens via permit.
        IERC20Permit(permit.token).permit(
            msg.sender,
            address(this),
            permit.approveAmount,
            permit.deadline,
            permit.v,
            permit.r,
            permit.s
        );

        amountOut = _swap(
            paths,
            amountOutMin
        );
    }

    /// @notice Wrapper function to allow pool deployment to be batched.
    function createPool(address _factory, bytes calldata data) external payable returns (address) {
        return IPoolFactory(_factory).createPool(data);
    }

    function stake(address stakingPool, address token, uint amount, address onBehalf) external {
        TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);

        if (IERC20(token).allowance(address(this), stakingPool) < amount) {
            TransferHelper.safeApprove(token, stakingPool, type(uint).max);
        }

        IStakingPool(stakingPool).stake(amount, onBehalf);
    }
}

File 2 of 20 : Multicall.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

/// @notice Helper utility that enables calling multiple local methods in a single call.
/// @author Modified from Uniswap (https://github.com/Uniswap/v3-periphery/blob/main/contracts/base/Multicall.sol)
/// License-Identifier: GPL-2.0-or-later
abstract contract Multicall {
    function multicall(bytes[] calldata data) public payable returns (bytes[] memory results) {
        results = new bytes[](data.length);
        
        for (uint i; i < data.length;) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]);

            if (!success) {
                // Next 5 lines from https://ethereum.stackexchange.com/a/83577
                if (result.length < 68) revert();
                assembly {
                    result := add(result, 0x04)
                }
                revert(abi.decode(result, (string)));
            }

            results[i] = result;

            // cannot realistically overflow on human timescales
            unchecked {
                ++i;
            }
        }
    }
}

// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

import "../interfaces/token/IERC20Permit2.sol";
import "../interfaces/token/IERC20PermitAllowed.sol";

abstract contract SelfPermit {
    function selfPermit(
        address token,
        uint value,
        uint deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable {
        IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s);
    }

    function selfPermitIfNecessary(
        address token,
        uint value,
        uint deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable {
        if (IERC20(token).allowance(msg.sender, address(this)) < value) {
            selfPermit(token, value, deadline, v, r, s);
        }
    }

    function selfPermitAllowed(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable {
        IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s);
    }

    function selfPermitAllowedIfNecessary(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable {
        if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) {
            selfPermitAllowed(token, nonce, expiry, v, r, s);
        }
    }

    function selfPermit2(
        address token,
        uint value,
        uint deadline,
        bytes calldata signature
    ) public payable {
        IERC20Permit2(token).permit2(msg.sender, address(this), value, deadline, signature);
    }

    function selfPermit2IfNecessary(
        address token,
        uint value,
        uint deadline,
        bytes calldata signature
    ) external payable {
        if (IERC20(token).allowance(msg.sender, address(this)) < value) {
            selfPermit2(token, value, deadline, signature);
        }
    }
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

interface IPoolFactory {
    function master() external view returns (address);

    function getDeployData() external view returns (bytes memory);

    function createPool(bytes calldata data) external returns (address pool);
}

File 5 of 20 : IRouter.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

interface IRouter {
    struct SwapStep {
        address pool;
        bytes data;
        address callback;
        bytes callbackData;
    }

    struct SwapPath {
        SwapStep[] steps;
        address tokenIn;
        uint amountIn;
    }

    struct SplitPermitParams {
        address token;
        uint approveAmount;
        uint deadline;
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    struct ArrayPermitParams {
        uint approveAmount;
        uint deadline;
        bytes signature;
    }
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

interface IStakingPool {
    function stake(uint amount, address onBehalf) external;
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

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

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IPool.sol";
import "../token/IERC20Permit2.sol";

interface IBasePool is IPool, IERC20Permit2 {
    function token0() external view returns (address);
    function token1() external view returns (address);

    function reserve0() external view returns (uint);
    function reserve1() external view returns (uint);
    function invariantLast() external view returns (uint);

    function getReserves() external view returns (uint, uint);
    function getAmountOut(address tokenIn, uint amountIn, address sender) external view returns (uint amountOut);
    function getAmountIn(address tokenOut, uint amountOut, address sender) external view returns (uint amountIn);

    event Mint(
        address indexed sender,
        uint amount0,
        uint amount1,
        uint liquidity,
        address indexed to
    );

    event Burn(
        address indexed sender,
        uint amount0,
        uint amount1,
        uint liquidity,
        address indexed to
    );

    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );

    event Sync(
        uint reserve0,
        uint reserve1
    );
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

interface IPool {
    struct TokenAmount {
        address token;
        uint amount;
    }

    /// @dev Returns the address of pool master.
    function master() external view returns (address);

    /// @dev Returns the vault.
    function vault() external view returns (address);

    /// @dev Returns the pool type.
    function poolType() external view returns (uint16);

    /// @dev Returns the assets of the pool.
    function getAssets() external view returns (address[] memory assets);

    /// @dev Returns the swap fee of the pool.
    function getSwapFee(address sender, address tokenIn, address tokenOut, bytes calldata data) external view returns (uint24 swapFee);

    /// @dev Returns the protocol fee of the pool.
    function getProtocolFee() external view returns (uint24 protocolFee);

    /// @dev Mints liquidity.
    function mint(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (uint liquidity);

    /// @dev Burns liquidity.
    function burn(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (TokenAmount[] memory tokenAmounts);

    /// @dev Burns liquidity with single output token.
    function burnSingle(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (TokenAmount memory tokenAmount);

    /// @dev Swaps between tokens.
    function swap(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (TokenAmount memory tokenAmount);
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IERC20Base.sol";

interface IERC20 is IERC20Base {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

interface IERC20Base {
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint amount) external returns (bool);
    function transfer(address to, uint amount) external returns (bool);
    function transferFrom(address from, address to, uint amount) external returns (bool);
    
    event Approval(address indexed owner, address indexed spender, uint amount);
    event Transfer(address indexed from, address indexed to, uint amount);
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IERC20.sol";

interface IERC20Permit is IERC20 {
    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
    function nonces(address owner) external view returns (uint);
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IERC20Permit.sol";

interface IERC20Permit2 is IERC20Permit {
    function permit2(address owner, address spender, uint amount, uint deadline, bytes calldata signature) external;
}

File 14 of 20 : IERC20PermitAllowed.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

/// @title Interface for permit
/// @notice Interface used by DAI/CHAI for permit
interface IERC20PermitAllowed {
    /// @notice Approve the spender to spend some tokens via the holder signature
    /// @dev This is the permit interface used by DAI and CHAI
    /// @param holder The address of the token holder, the token owner
    /// @param spender The address of the token spender
    /// @param nonce The holder's nonce, increases at each call to permit
    /// @param expiry The timestamp at which the permit is no longer valid
    /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function permit(
        address holder,
        address spender,
        uint256 nonce,
        uint256 expiry,
        bool allowed,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

File 15 of 20 : IERC3156FlashBorrower.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

interface IERC3156FlashBorrower {
    /**
     * @dev Receive a flash loan.
     * @param initiator The initiator of the loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param fee The additional amount of tokens to repay.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
     */
    function onFlashLoan(
        address initiator,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external returns (bytes32);
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IERC3156FlashBorrower.sol";

interface IERC3156FlashLender {
    /**
     * @dev The amount of currency available to be lent.
     * @param token The loan currency.
     * @return The amount of `token` that can be borrowed.
     */
    function maxFlashLoan(
        address token
    ) external view returns (uint256);

    /**
     * @dev The fee to be charged for a given loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @return The amount of `token` to be charged for the loan, on top of the returned principal.
     */
    function flashFee(
        address token,
        uint256 amount
    ) external view returns (uint256);

    /**
     * @dev Initiate a flash loan.
     * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     */
    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external returns (bool);
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IFlashLoanRecipient.sol";
import "./IERC3156FlashLender.sol";

interface IFlashLoan is IERC3156FlashLender {
    function flashLoanFeePercentage() external view returns (uint);

    /**
     * @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,
     * and then reverting unless the tokens plus a proportional protocol fee have been returned.
     *
     * The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount
     * for each token contract. `tokens` must be sorted in ascending order.
     *
     * The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the
     * `receiveFlashLoan` call.
     *
     * Emits `FlashLoan` events.
     */
    function flashLoanMultiple(
        IFlashLoanRecipient recipient,
        address[] memory tokens,
        uint[] memory amounts,
        bytes memory userData
    ) external;

    /**
     * @dev Emitted for each individual flash loan performed by `flashLoan`.
     */
    event FlashLoan(address indexed recipient, address indexed token, uint amount, uint feeAmount);
}

File 18 of 20 : IFlashLoanRecipient.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.7.0 <0.9.0;

// Inspired by Aave Protocol's IFlashLoanReceiver.

interface IFlashLoanRecipient {
    /**
     * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient.
     *
     * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this
     * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the
     * Vault, or else the entire flash loan will revert.
     *
     * `userData` is the same value passed in the `IVault.flashLoan` call.
     */
    function receiveFlashLoan(
        address[] memory tokens,
        uint[] memory amounts,
        uint[] memory feeAmounts,
        bytes memory userData
    ) external;
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.5.0;

import "./IFlashLoan.sol";

interface IVault is IFlashLoan {
    function wETH() external view returns (address);

    function reserves(address token) external view returns (uint reserve);

    function balanceOf(address token, address owner) external view returns (uint balance);

    function deposit(address token, address to) external payable returns (uint amount);

    function depositETH(address to) external payable returns (uint amount);

    function transferAndDeposit(address token, address to, uint amount) external payable returns (uint);

    function transfer(address token, address to, uint amount) external;

    function withdraw(address token, address to, uint amount) external;

    function withdrawAlternative(address token, address to, uint amount, uint8 mode) external;

    function withdrawETH(address to, uint amount) external;
}

// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity ^0.8.0;

/// @dev The ETH transfer has failed.
error ETHTransferFailed();

/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();

/// @dev The ERC20 `transfer` has failed.
error TransferFailed();

/// @dev The ERC20 `approve` has failed.
error ApproveFailed();

/// @dev Helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true / false.
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint value
    ) internal {
        // bytes4(keccak256(bytes("approve(address,uint256)")));
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert ApproveFailed();
        }
    }

    function safeTransfer(
        address token,
        address to,
        uint value
    ) internal {
        // bytes4(keccak256(bytes("transfer(address,uint256)")));
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert TransferFailed();
        }
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint value
    ) internal {
        // bytes4(keccak256(bytes("transferFrom(address,address,uint256)")));
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert TransferFromFailed();
        }
    }

    function safeTransferETH(address to, uint value) internal {
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, ) = to.call{value: value}("");

        if (!success) {
            revert ETHTransferFailed();
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200,
    "details": {
      "yul": false
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_wETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApproveFailed","type":"error"},{"inputs":[],"name":"Expired","type":"error"},{"inputs":[],"name":"NotEnoughLiquidityMinted","type":"error"},{"inputs":[],"name":"TooLittleReceived","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct SyncSwapRouter.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct SyncSwapRouter.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"addLiquidity2","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct SyncSwapRouter.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams[]","name":"permits","type":"tuple[]"}],"name":"addLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct SyncSwapRouter.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams[]","name":"permits","type":"tuple[]"}],"name":"addLiquidityWithPermit2","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256[]","name":"minAmounts","type":"uint256[]"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"burnLiquidity","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount[]","name":"amounts","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"burnLiquiditySingle","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IRouter.ArrayPermitParams","name":"permit","type":"tuple"}],"name":"burnLiquiditySingleWithPermit","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256[]","name":"minAmounts","type":"uint256[]"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IRouter.ArrayPermitParams","name":"permit","type":"tuple"}],"name":"burnLiquidityWithPermit","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount[]","name":"amounts","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"createPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"enteredPools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"enteredPoolsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isPoolEntered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"selfPermit2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"selfPermit2IfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowed","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowedIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingPool","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"onBehalf","type":"address"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"internalType":"struct IRouter.SwapStep[]","name":"steps","type":"tuple[]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"internalType":"struct IRouter.SwapPath[]","name":"paths","type":"tuple[]"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swap","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"internalType":"struct IRouter.SwapStep[]","name":"steps","type":"tuple[]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"internalType":"struct IRouter.SwapPath[]","name":"paths","type":"tuple[]"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams","name":"permit","type":"tuple"}],"name":"swapWithPermit","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c06040523480156200001157600080fd5b506040516200318438038062003184833981016040819052620000349162000086565b6001600160a01b039182166080521660a052620000c9565b60006001600160a01b0382165b92915050565b6200006a816200004c565b81146200007657600080fd5b50565b805162000059816200005f565b600080604083850312156200009e576200009e600080fd5b6000620000ac858562000079565b9250506020620000bf8582860162000079565b9150509250929050565b60805160a0516130806200010460003960006103e00152600081816104270152818161179801528181611821015261185d01526130806000f3fe60806040526004361061014b5760003560e01c80639dd41df2116100b6578063c4b3fc401161006f578063c4b3fc4014610395578063ced78795146103a8578063e84d494b146103bb578063f2428621146103ce578063f3995c6714610402578063fbfa77cf1461041557600080fd5b80639dd41df2146102e6578063a4a78f0c146102f9578063ac9650d81461030c578063ad271fa31461032c578063b956b3fb1461034c578063c2e3140a1461038257600080fd5b80636291027c116101085780636291027c1461024d578063688ee44c1461026d5780636cbe96fa146102805780636cc781cd146102a05780637d10c9d6146102b357806394ec6d78146102d357600080fd5b80632b4abadb146101505780632cc4081e14610186578063353766c6146101a65780634659a494146101d35780634f25b858146101e857806353c43f151461022d575b600080fd5b34801561015c57600080fd5b5061017061016b36600461191a565b610449565b60405161017d9190611966565b60405180910390f35b610199610194366004611ce1565b610481565b60405161017d9190611d74565b3480156101b257600080fd5b506101c66101c1366004611e89565b6104ca565b60405161017d9190611ffa565b6101e66101e136600461201f565b6105c3565b005b3480156101f457600080fd5b506102206102033660046120a9565b600060208181529281526040808220909352908152205460ff1681565b60405161017d91906120e4565b34801561023957600080fd5b506101996102483660046120f2565b610638565b34801561025957600080fd5b506101e66102683660046121a3565b610665565b6101e661027b366004612207565b61075b565b61029361028e3660046122d4565b6107e6565b60405161017d91906123ba565b6101e66102ae366004612207565b610807565b3480156102bf57600080fd5b506101996102ce3660046123e3565b610876565b6102936102e13660046122d4565b61091c565b6101706102f43660046124d0565b610947565b6101e661030736600461201f565b6109c5565b61031f61031a36600461252b565b610a54565b60405161017d9190612644565b34801561033857600080fd5b506101c6610347366004612655565b610ba9565b34801561035857600080fd5b506102936103673660046126fe565b6001600160a01b031660009081526001602052604090205490565b6101e661039036600461201f565b610c22565b6102936103a3366004612830565b610ca7565b6102936103b6366004612830565b610db4565b6101996103c9366004612947565b610dd3565b3480156103da57600080fd5b506101707f000000000000000000000000000000000000000000000000000000000000000081565b6101e661041036600461201f565b610eb2565b34801561042157600080fd5b506101707f000000000000000000000000000000000000000000000000000000000000000081565b6001602052816000526040600020818154811061046557600080fd5b6000918252602090912001546001600160a01b03169150829050565b604080518082019091526000808252602082015281804211156104b757604051630407b05b60e31b815260040160405180910390fd5b6104c18585610eea565b95945050505050565b805160208201516040808401519051630b00663360e21b81526060936001600160a01b038f1693632c0198cc9361050b9333933093909290916004016129b9565b600060405180830381600087803b15801561052557600080fd5b505af1158015610539573d6000803e3d6000fd5b505050506105b48b8b8b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284376000920191909152508c92508b91508a9050611176565b9b9a5050505050505050505050565b6040516323f2ebc360e21b81526001600160a01b03871690638fcbaf0c906105fe90339030908a908a906001908b908b908b90600401612a09565b600060405180830381600087803b15801561061857600080fd5b505af115801561062c573d6000803e3d6000fd5b50505050505050505050565b604080518082019091526000808252602082015261065a8787878787876112e4565b979650505050505050565b61067183333085611405565b604051636eb1769f60e11b815282906001600160a01b0385169063dd62ed3e906106a19030908990600401612a73565b602060405180830381865afa1580156106be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e29190612a99565b10156106f5576106f583856000196114f3565b604051637acb775760e01b81526001600160a01b03851690637acb7757906107239085908590600401612aba565b600060405180830381600087803b15801561073d57600080fd5b505af1158015610751573d6000803e3d6000fd5b5050505050505050565b604051636eb1769f60e11b815284906001600160a01b0387169063dd62ed3e9061078b9033903090600401612a73565b602060405180830381865afa1580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190612a99565b10156107df576107df8585858585610807565b5050505050565b60006107f98a8a8a8a8a8a8a8a8a6115df565b9a9950505050505050505050565b604051630b00663360e21b81526001600160a01b03861690632c0198cc9061083d90339030908990899089908990600401612aeb565b600060405180830381600087803b15801561085757600080fd5b505af115801561086b573d6000803e3d6000fd5b505050505050505050565b60408051808201909152600080825260208201526001600160a01b038816632c0198cc3330853560208701356108af6040890189612b33565b6040518763ffffffff1660e01b81526004016108d096959493929190612aeb565b600060405180830381600087803b1580156108ea57600080fd5b505af11580156108fe573d6000803e3d6000fd5b505050506109108888888888886112e4565b98975050505050505050565b600061092f8a8a8a8a8a8a8a8a8a6115df565b905061093a8a6116f4565b9998505050505050505050565b6040516313b8683f60e01b81526000906001600160a01b038516906313b8683f906109789086908690600401612b91565b6020604051808303816000875af1158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb9190612bae565b90505b9392505050565b604051636eb1769f60e11b8152600019906001600160a01b0388169063dd62ed3e906109f79033903090600401612a73565b602060405180830381865afa158015610a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a389190612a99565b1015610a4c57610a4c8686868686866105c3565b505050505050565b6060816001600160401b03811115610a6e57610a6e611974565b604051908082528060200260200182016040528015610aa157816020015b6060815260200190600190039081610a8c5790505b50905060005b82811015610ba25760008030868685818110610ac557610ac5612bcf565b9050602002810190610ad79190612b33565b604051610ae5929190612bf8565b600060405180830381855af49150503d8060008114610b20576040519150601f19603f3d011682016040523d82523d6000602084013e610b25565b606091505b509150915081610b7a57604481511015610b3e57600080fd5b60048101905080806020019051810190610b589190612c5d565b60405162461bcd60e51b8152600401610b719190612c97565b60405180910390fd5b80848481518110610b8d57610b8d612bcf565b60209081029190910101525050600101610aa7565b5092915050565b60606107f98a8a8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92508a9150899050611176565b604051636eb1769f60e11b815285906001600160a01b0388169063dd62ed3e90610c529033903090600401612a73565b602060405180830381865afa158015610c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c939190612a99565b1015610a4c57610a4c868686868686610eb2565b80516040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905290919060005b82811015610d9157848181518110610cfa57610cfa612bcf565b6020026020010151915081600001516001600160a01b031663d505accf333085602001518660400151876060015188608001518960a001516040518863ffffffff1660e01b8152600401610d549796959493929190612ca8565b600060405180830381600087803b158015610d6e57600080fd5b505af1158015610d82573d6000803e3d6000fd5b50505050806001019050610ce0565b50610da38d8d8d8d8d8d8d8d8d6115df565b9d9c50505050505050505050505050565b6000610dc88b8b8b8b8b8b8b8b8b8b610ca7565b90506107f98b6116f4565b60408051808201909152600080825260208201528280421115610e0957604051630407b05b60e31b815260040160405180910390fd5b610e1660208401846126fe565b6001600160a01b031663d505accf333060208701356040880135610e4060808a0160608b01612d04565b89608001358a60a001356040518863ffffffff1660e01b8152600401610e6c9796959493929190612ca8565b600060405180830381600087803b158015610e8657600080fd5b505af1158015610e9a573d6000803e3d6000fd5b50505050610ea88686610eea565b9695505050505050565b60405163d505accf60e01b81526001600160a01b0387169063d505accf906105fe90339030908a908a908a908a908a90600401612ca8565b604080518082019091526000808252602082015282516040805160608082018352808252600060208084018290528385018290528451608081018652828152808201849052808601839052808401939093528451808601909552818552840152909160008060005b8681101561114457898181518110610f6c57610f6c612bcf565b602002602001015195508560000151600081518110610f8d57610f8d612bcf565b60200260200101519450610fae866020015186600001518860400151611773565b8551519250600091505b8282101561113c57610fcb600184612d3b565b82036110855784600001516001600160a01b0316637132bb7f866020015133886040015189606001516040518563ffffffff1660e01b81526004016110139493929190612d52565b60408051808303816000875af1158015611031573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110559190612ddb565b80516001600160a01b03168952602080820151908a018051929650909161107d908390612dfc565b90525061113c565b84600001516001600160a01b0316637132bb7f866020015133886040015189606001516040518563ffffffff1660e01b81526004016110c79493929190612d52565b60408051808303816000875af11580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111099190612ddb565b508551611117836001612dfc565b8151811061112757611127612bcf565b60200260200101519450816001019150610fb8565b600101610f52565b50878760200151101561116a5760405163c9f52c7160e01b815260040160405180910390fd5b50505050505092915050565b6040516323b872dd60e01b81526060906001600160a01b038916906323b872dd906111a99033908c908c90600401612e14565b6020604051808303816000875af11580156111c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ec9190612e4f565b5060405163f66eab5b60e01b81526001600160a01b0389169063f66eab5b906112219089903390899089908990600401612e70565b6000604051808303816000875af1158015611240573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112689190810190612f27565b805190915060005b818110156112d75786818151811061128a5761128a612bcf565b60200260200101518382815181106112a4576112a4612bcf565b60200260200101516020015110156112cf5760405163c9f52c7160e01b815260040160405180910390fd5b600101611270565b5050979650505050505050565b6040805180820182526000808252602082015290516323b872dd60e01b81526001600160a01b038816906323b872dd906113269033908b908b90600401612e14565b6020604051808303816000875af1158015611345573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113699190612e4f565b506040516313d85e7560e11b81526001600160a01b038816906327b0bcea9061139c908890339088908890600401612d52565b60408051808303816000875af11580156113ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113de9190612ddb565b90508381602001511015610ea85760405163c9f52c7160e01b815260040160405180910390fd5b600080856001600160a01b03166323b872dd86868660405160240161142c93929190612e14565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516114659190612f83565b6000604051808303816000865af19150503d80600081146114a2576040519150601f19603f3d011682016040523d82523d6000602084013e6114a7565b606091505b50915091508115806114d557508051158015906114d55750808060200190518101906114d39190612e4f565b155b15610a4c57604051631e4e7d0960e21b815260040160405180910390fd5b600080846001600160a01b031663095ea7b38585604051602401611518929190612f8f565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516115519190612f83565b6000604051808303816000865af19150503d806000811461158e576040519150601f19603f3d011682016040523d82523d6000602084013e611593565b606091505b50915091508115806115c157508051158015906115c15750808060200190518101906115bf9190612e4f565b155b156107df57604051633e3f8f7360e01b815260040160405180910390fd5b6040805180820190915260008082526020820181905290889060005b82811015611648578b8b8281811061161557611615612bcf565b90506040020180360381019061162b9190612fe8565b915061164082600001518e8460200151611773565b6001016115fb565b506040516301f3943560e11b81526001600160a01b038d16906303e7286a9061167f908c908c9033908c908c908c90600401613009565b6020604051808303816000875af115801561169e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c29190612a99565b9250868310156116e55760405163124ca15f60e11b815260040160405180910390fd5b50509998505050505050505050565b6001600160a01b03811660009081526020818152604080832033845290915290205460ff16611770576001600160a01b0381166000818152602081815260408083203384528252808320805460ff1916600190811790915580835290832080549182018155835291200180546001600160a01b03191690911790555b50565b6001600160a01b03831661181a57604051631f2c13e160e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f9609f089083906117d19087908790600401612a73565b60206040518083038185885af11580156117ef573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906118149190612a99565b50505050565b61184683337f000000000000000000000000000000000000000000000000000000000000000084611405565b604051631f2c13e160e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f9609f08906118949086908690600401612a73565b6020604051808303816000875af11580156118b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118149190612a99565b60006001600160a01b0382165b92915050565b6118f3816118d7565b811461177057600080fd5b80356118e4816118ea565b806118f3565b80356118e481611909565b6000806040838503121561193057611930600080fd5b600061193c85856118fe565b925050602061194d8582860161190f565b9150509250929050565b611960816118d7565b82525050565b602081016118e48284611957565b634e487b7160e01b600052604160045260246000fd5b601f19601f83011681018181106001600160401b03821117156119af576119af611974565b6040525050565b60006119c160405190565b90506119cd828261198a565b919050565b60006001600160401b038211156119eb576119eb611974565b5060209081020190565b60006001600160401b03821115611a0e57611a0e611974565b601f19601f83011660200192915050565b82818337506000910152565b6000611a3e611a39846119f5565b6119b6565b905082815260208101848484011115611a5957611a59600080fd5b611a64848285611a1f565b509392505050565b600082601f830112611a8057611a80600080fd5b8135611a90848260208601611a2b565b949350505050565b600060808284031215611aad57611aad600080fd5b611ab760806119b6565b90506000611ac584846118fe565b82525060208201356001600160401b03811115611ae457611ae4600080fd5b611af084828501611a6c565b6020830152506040611b04848285016118fe565b60408301525060608201356001600160401b03811115611b2657611b26600080fd5b611b3284828501611a6c565b60608301525092915050565b6000611b4c611a39846119d2565b83815290506020808201908402830185811115611b6b57611b6b600080fd5b835b81811015611bab5780356001600160401b03811115611b8e57611b8e600080fd5b808601611b9b8982611a98565b8552505060209283019201611b6d565b5050509392505050565b600082601f830112611bc957611bc9600080fd5b8135611a90848260208601611b3e565b600060608284031215611bee57611bee600080fd5b611bf860606119b6565b905081356001600160401b03811115611c1357611c13600080fd5b611c1f84828501611bb5565b8252506020611c30848483016118fe565b6020830152506040611c448482850161190f565b60408301525092915050565b6000611c5e611a39846119d2565b83815290506020808201908402830185811115611c7d57611c7d600080fd5b835b81811015611bab5780356001600160401b03811115611ca057611ca0600080fd5b808601611cad8982611bd9565b8552505060209283019201611c7f565b600082601f830112611cd157611cd1600080fd5b8135611a90848260208601611c50565b600080600060608486031215611cf957611cf9600080fd5b83356001600160401b03811115611d1257611d12600080fd5b611d1e86828701611cbd565b9350506020611d2f8682870161190f565b9250506040611d408682870161190f565b9150509250925092565b80611960565b80516040830190611d618482611957565b5060208201516118146020850182611d4a565b604081016118e48284611d50565b60008083601f840112611d9757611d97600080fd5b5081356001600160401b03811115611db157611db1600080fd5b602083019150836001820283011115611dcc57611dcc600080fd5b9250929050565b60008083601f840112611de857611de8600080fd5b5081356001600160401b03811115611e0257611e02600080fd5b602083019150836020820283011115611dcc57611dcc600080fd5b600060608284031215611e3257611e32600080fd5b611e3c60606119b6565b90506000611e4a848461190f565b8252506020611e5b8484830161190f565b60208301525060408201356001600160401b03811115611e7d57611e7d600080fd5b611c4484828501611a6c565b60008060008060008060008060008060e08b8d031215611eab57611eab600080fd5b6000611eb78d8d6118fe565b9a50506020611ec88d828e0161190f565b99505060408b01356001600160401b03811115611ee757611ee7600080fd5b611ef38d828e01611d82565b985098505060608b01356001600160401b03811115611f1457611f14600080fd5b611f208d828e01611dd3565b96509650506080611f338d828e016118fe565b94505060a08b01356001600160401b03811115611f5257611f52600080fd5b611f5e8d828e01611d82565b935093505060c08b01356001600160401b03811115611f7f57611f7f600080fd5b611f8b8d828e01611e1d565b9150509295989b9194979a5092959850565b6000611fa98383611d50565b505060400190565b6000611fbb825190565b80845260209384019383018060005b83811015611fef578151611fde8882611f9d565b975060208301925050600101611fca565b509495945050505050565b602080825281016109be8184611fb1565b60ff81166118f3565b80356118e48161200b565b60008060008060008060c0878903121561203b5761203b600080fd5b600061204789896118fe565b965050602061205889828a0161190f565b955050604061206989828a0161190f565b945050606061207a89828a01612014565b935050608061208b89828a0161190f565b92505060a061209c89828a0161190f565b9150509295509295509295565b600080604083850312156120bf576120bf600080fd5b60006120cb85856118fe565b925050602061194d858286016118fe565b801515611960565b602081016118e482846120dc565b60008060008060008060c0878903121561210e5761210e600080fd5b600061211a89896118fe565b965050602061212b89828a0161190f565b95505060408701356001600160401b0381111561214a5761214a600080fd5b61215689828a01611a6c565b945050606061216789828a0161190f565b935050608061217889828a016118fe565b92505060a08701356001600160401b0381111561219757612197600080fd5b61209c89828a01611a6c565b600080600080608085870312156121bc576121bc600080fd5b60006121c887876118fe565b94505060206121d9878288016118fe565b93505060406121ea8782880161190f565b92505060606121fb878288016118fe565b91505092959194509250565b60008060008060006080868803121561222257612222600080fd5b600061222e88886118fe565b955050602061223f8882890161190f565b94505060406122508882890161190f565b93505060608601356001600160401b0381111561226f5761226f600080fd5b61227b88828901611d82565b92509250509295509295909350565b60008083601f84011261229f5761229f600080fd5b5081356001600160401b038111156122b9576122b9600080fd5b602083019150836040820283011115611dcc57611dcc600080fd5b600080600080600080600080600060c08a8c0312156122f5576122f5600080fd5b60006123018c8c6118fe565b99505060208a01356001600160401b0381111561232057612320600080fd5b61232c8c828d0161228a565b985098505060408a01356001600160401b0381111561234d5761234d600080fd5b6123598c828d01611d82565b9650965050606061236c8c828d0161190f565b945050608061237d8c828d016118fe565b93505060a08a01356001600160401b0381111561239c5761239c600080fd5b6123a88c828d01611d82565b92509250509295985092959850929598565b602081016118e48284611d4a565b6000606082840312156123dd576123dd600080fd5b50919050565b600080600080600080600060e0888a03121561240157612401600080fd5b600061240d8a8a6118fe565b975050602061241e8a828b0161190f565b96505060408801356001600160401b0381111561243d5761243d600080fd5b6124498a828b01611a6c565b955050606061245a8a828b0161190f565b945050608061246b8a828b016118fe565b93505060a08801356001600160401b0381111561248a5761248a600080fd5b6124968a828b01611a6c565b92505060c08801356001600160401b038111156124b5576124b5600080fd5b6124c18a828b016123c8565b91505092959891949750929550565b6000806000604084860312156124e8576124e8600080fd5b60006124f486866118fe565b93505060208401356001600160401b0381111561251357612513600080fd5b61251f86828701611d82565b92509250509250925092565b6000806020838503121561254157612541600080fd5b82356001600160401b0381111561255a5761255a600080fd5b61256685828601611dd3565b92509250509250929050565b60005b8381101561258d578181015183820152602001612575565b838111156118145750506000910152565b60006125a8825190565b8084526020840193506125bf818560208601612572565b601f19601f8201165b9093019392505050565b60006109be838361259e565b60006125e8825190565b808452602084019350836020820285016126028560200190565b8060005b85811015612637578484038952815161261f85826125d2565b94506020830160209a909a0199925050600101612606565b5091979650505050505050565b602080825281016109be81846125de565b600080600080600080600080600060c08a8c03121561267657612676600080fd5b60006126828c8c6118fe565b99505060206126938c828d0161190f565b98505060408a01356001600160401b038111156126b2576126b2600080fd5b6126be8c828d01611d82565b975097505060608a01356001600160401b038111156126df576126df600080fd5b6126eb8c828d01611dd3565b9550955050608061237d8c828d016118fe565b60006020828403121561271357612713600080fd5b6000611a9084846118fe565b600060c0828403121561273457612734600080fd5b61273e60c06119b6565b9050600061274c84846118fe565b825250602061275d8484830161190f565b60208301525060406127718482850161190f565b604083015250606061278584828501612014565b60608301525060806127998482850161190f565b60808301525060a06127ad8482850161190f565b60a08301525092915050565b60006127c7611a39846119d2565b83815290506020810160c084028301858111156127e6576127e6600080fd5b835b81811015611bab57806127fb888261271f565b84525060209092019160c0016127e8565b600082601f83011261282057612820600080fd5b8135611a908482602086016127b9565b60008060008060008060008060008060e08b8d03121561285257612852600080fd5b600061285e8d8d6118fe565b9a505060208b01356001600160401b0381111561287d5761287d600080fd5b6128898d828e0161228a565b995099505060408b01356001600160401b038111156128aa576128aa600080fd5b6128b68d828e01611d82565b975097505060606128c98d828e0161190f565b95505060806128da8d828e016118fe565b94505060a08b01356001600160401b038111156128f9576128f9600080fd5b6129058d828e01611d82565b935093505060c08b01356001600160401b0381111561292657612926600080fd5b611f8b8d828e0161280c565b600060c082840312156123dd576123dd600080fd5b600080600080610120858703121561296157612961600080fd5b84356001600160401b0381111561297a5761297a600080fd5b61298687828801611cbd565b94505060206129978782880161190f565b93505060406129a88782880161190f565b92505060606121fb87828801612932565b60a081016129c78288611957565b6129d46020830187611957565b6129e16040830186611d4a565b6129ee6060830185611d4a565b818103608083015261065a818461259e565b60ff8116611960565b6101008101612a18828b611957565b612a25602083018a611957565b612a326040830189611d4a565b612a3f6060830188611d4a565b612a4c60808301876120dc565b612a5960a0830186612a00565b612a6660c0830185611d4a565b61093a60e0830184611d4a565b60408101612a818285611957565b6109be6020830184611957565b80516118e481611909565b600060208284031215612aae57612aae600080fd5b6000611a908484612a8e565b60408101612a818285611d4a565b8183526000602084019350612ade838584611a1f565b601f19601f8401166125c8565b60a08101612af98289611957565b612b066020830188611957565b612b136040830187611d4a565b612b206060830186611d4a565b8181036080830152610910818486612ac8565b6000808335601e1936859003018112612b4e57612b4e600080fd5b8084019250823591506001600160401b03821115612b6e57612b6e600080fd5b602083019250600182023603831315612b8957612b89600080fd5b509250929050565b602080825281016109bb818486612ac8565b80516118e4816118ea565b600060208284031215612bc357612bc3600080fd5b6000611a908484612ba3565b634e487b7160e01b600052603260045260246000fd5b6000612bf2838584611a1f565b50500190565b6000611a90828486612be5565b6000612c13611a39846119f5565b905082815260208101848484011115612c2e57612c2e600080fd5b611a64848285612572565b600082601f830112612c4d57612c4d600080fd5b8151611a90848260208601612c05565b600060208284031215612c7257612c72600080fd5b81516001600160401b03811115612c8b57612c8b600080fd5b611a9084828501612c39565b602080825281016109be818461259e565b60e08101612cb6828a611957565b612cc36020830189611957565b612cd06040830188611d4a565b612cdd6060830187611d4a565b612cea6080830186612a00565b612cf760a0830185611d4a565b61091060c0830184611d4a565b600060208284031215612d1957612d19600080fd5b6000611a908484612014565b634e487b7160e01b600052601160045260246000fd5b600082821015612d4d57612d4d612d25565b500390565b60808082528101612d63818761259e565b9050612d726020830186611957565b612d7f6040830185611957565b8181036060830152610ea8818461259e565b600060408284031215612da657612da6600080fd5b612db060406119b6565b90506000612dbe8484612ba3565b8252506020612dcf84848301612a8e565b60208301525092915050565b600060408284031215612df057612df0600080fd5b6000611a908484612d91565b60008219821115612e0f57612e0f612d25565b500190565b60608101612e228286611957565b612e2f6020830185611957565b611a906040830184611d4a565b8015156118f3565b80516118e481612e3c565b600060208284031215612e6457612e64600080fd5b6000611a908484612e44565b60808082528101612e81818861259e565b9050612e906020830187611957565b612e9d6040830186611957565b818103606083015261065a818486612ac8565b6000612ebe611a39846119d2565b83815290506020810160408402830185811115612edd57612edd600080fd5b835b81811015611bab5780612ef28882612d91565b845250602090920191604001612edf565b600082601f830112612f1757612f17600080fd5b8151611a90848260208601612eb0565b600060208284031215612f3c57612f3c600080fd5b81516001600160401b03811115612f5557612f55600080fd5b611a9084828501612f03565b6000612f6b825190565b612f79818560208601612572565b9290920192915050565b60006109be8284612f61565b60408101612f9d8285611957565b6109be6020830184611d4a565b600060408284031215612fbf57612fbf600080fd5b612fc960406119b6565b90506000612fd784846118fe565b8252506020612dcf8484830161190f565b600060408284031215612ffd57612ffd600080fd5b6000611a908484612faa565b6080808252810161301b81888a612ac8565b905061302a6020830187611957565b6130376040830186611957565b8181036060830152610910818486612ac856fea264697066735822122021d6dea4e36ea46e8e3b1cdfed26aba18483ad533843a5be49c86ecbdef0e8d964736f6c634300080f00330000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f

Deployed Bytecode

0x60806040526004361061014b5760003560e01c80639dd41df2116100b6578063c4b3fc401161006f578063c4b3fc4014610395578063ced78795146103a8578063e84d494b146103bb578063f2428621146103ce578063f3995c6714610402578063fbfa77cf1461041557600080fd5b80639dd41df2146102e6578063a4a78f0c146102f9578063ac9650d81461030c578063ad271fa31461032c578063b956b3fb1461034c578063c2e3140a1461038257600080fd5b80636291027c116101085780636291027c1461024d578063688ee44c1461026d5780636cbe96fa146102805780636cc781cd146102a05780637d10c9d6146102b357806394ec6d78146102d357600080fd5b80632b4abadb146101505780632cc4081e14610186578063353766c6146101a65780634659a494146101d35780634f25b858146101e857806353c43f151461022d575b600080fd5b34801561015c57600080fd5b5061017061016b36600461191a565b610449565b60405161017d9190611966565b60405180910390f35b610199610194366004611ce1565b610481565b60405161017d9190611d74565b3480156101b257600080fd5b506101c66101c1366004611e89565b6104ca565b60405161017d9190611ffa565b6101e66101e136600461201f565b6105c3565b005b3480156101f457600080fd5b506102206102033660046120a9565b600060208181529281526040808220909352908152205460ff1681565b60405161017d91906120e4565b34801561023957600080fd5b506101996102483660046120f2565b610638565b34801561025957600080fd5b506101e66102683660046121a3565b610665565b6101e661027b366004612207565b61075b565b61029361028e3660046122d4565b6107e6565b60405161017d91906123ba565b6101e66102ae366004612207565b610807565b3480156102bf57600080fd5b506101996102ce3660046123e3565b610876565b6102936102e13660046122d4565b61091c565b6101706102f43660046124d0565b610947565b6101e661030736600461201f565b6109c5565b61031f61031a36600461252b565b610a54565b60405161017d9190612644565b34801561033857600080fd5b506101c6610347366004612655565b610ba9565b34801561035857600080fd5b506102936103673660046126fe565b6001600160a01b031660009081526001602052604090205490565b6101e661039036600461201f565b610c22565b6102936103a3366004612830565b610ca7565b6102936103b6366004612830565b610db4565b6101996103c9366004612947565b610dd3565b3480156103da57600080fd5b506101707f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f81565b6101e661041036600461201f565b610eb2565b34801561042157600080fd5b506101707f0000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b81565b6001602052816000526040600020818154811061046557600080fd5b6000918252602090912001546001600160a01b03169150829050565b604080518082019091526000808252602082015281804211156104b757604051630407b05b60e31b815260040160405180910390fd5b6104c18585610eea565b95945050505050565b805160208201516040808401519051630b00663360e21b81526060936001600160a01b038f1693632c0198cc9361050b9333933093909290916004016129b9565b600060405180830381600087803b15801561052557600080fd5b505af1158015610539573d6000803e3d6000fd5b505050506105b48b8b8b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284376000920191909152508c92508b91508a9050611176565b9b9a5050505050505050505050565b6040516323f2ebc360e21b81526001600160a01b03871690638fcbaf0c906105fe90339030908a908a906001908b908b908b90600401612a09565b600060405180830381600087803b15801561061857600080fd5b505af115801561062c573d6000803e3d6000fd5b50505050505050505050565b604080518082019091526000808252602082015261065a8787878787876112e4565b979650505050505050565b61067183333085611405565b604051636eb1769f60e11b815282906001600160a01b0385169063dd62ed3e906106a19030908990600401612a73565b602060405180830381865afa1580156106be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e29190612a99565b10156106f5576106f583856000196114f3565b604051637acb775760e01b81526001600160a01b03851690637acb7757906107239085908590600401612aba565b600060405180830381600087803b15801561073d57600080fd5b505af1158015610751573d6000803e3d6000fd5b5050505050505050565b604051636eb1769f60e11b815284906001600160a01b0387169063dd62ed3e9061078b9033903090600401612a73565b602060405180830381865afa1580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190612a99565b10156107df576107df8585858585610807565b5050505050565b60006107f98a8a8a8a8a8a8a8a8a6115df565b9a9950505050505050505050565b604051630b00663360e21b81526001600160a01b03861690632c0198cc9061083d90339030908990899089908990600401612aeb565b600060405180830381600087803b15801561085757600080fd5b505af115801561086b573d6000803e3d6000fd5b505050505050505050565b60408051808201909152600080825260208201526001600160a01b038816632c0198cc3330853560208701356108af6040890189612b33565b6040518763ffffffff1660e01b81526004016108d096959493929190612aeb565b600060405180830381600087803b1580156108ea57600080fd5b505af11580156108fe573d6000803e3d6000fd5b505050506109108888888888886112e4565b98975050505050505050565b600061092f8a8a8a8a8a8a8a8a8a6115df565b905061093a8a6116f4565b9998505050505050505050565b6040516313b8683f60e01b81526000906001600160a01b038516906313b8683f906109789086908690600401612b91565b6020604051808303816000875af1158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb9190612bae565b90505b9392505050565b604051636eb1769f60e11b8152600019906001600160a01b0388169063dd62ed3e906109f79033903090600401612a73565b602060405180830381865afa158015610a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a389190612a99565b1015610a4c57610a4c8686868686866105c3565b505050505050565b6060816001600160401b03811115610a6e57610a6e611974565b604051908082528060200260200182016040528015610aa157816020015b6060815260200190600190039081610a8c5790505b50905060005b82811015610ba25760008030868685818110610ac557610ac5612bcf565b9050602002810190610ad79190612b33565b604051610ae5929190612bf8565b600060405180830381855af49150503d8060008114610b20576040519150601f19603f3d011682016040523d82523d6000602084013e610b25565b606091505b509150915081610b7a57604481511015610b3e57600080fd5b60048101905080806020019051810190610b589190612c5d565b60405162461bcd60e51b8152600401610b719190612c97565b60405180910390fd5b80848481518110610b8d57610b8d612bcf565b60209081029190910101525050600101610aa7565b5092915050565b60606107f98a8a8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92508a9150899050611176565b604051636eb1769f60e11b815285906001600160a01b0388169063dd62ed3e90610c529033903090600401612a73565b602060405180830381865afa158015610c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c939190612a99565b1015610a4c57610a4c868686868686610eb2565b80516040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905290919060005b82811015610d9157848181518110610cfa57610cfa612bcf565b6020026020010151915081600001516001600160a01b031663d505accf333085602001518660400151876060015188608001518960a001516040518863ffffffff1660e01b8152600401610d549796959493929190612ca8565b600060405180830381600087803b158015610d6e57600080fd5b505af1158015610d82573d6000803e3d6000fd5b50505050806001019050610ce0565b50610da38d8d8d8d8d8d8d8d8d6115df565b9d9c50505050505050505050505050565b6000610dc88b8b8b8b8b8b8b8b8b8b610ca7565b90506107f98b6116f4565b60408051808201909152600080825260208201528280421115610e0957604051630407b05b60e31b815260040160405180910390fd5b610e1660208401846126fe565b6001600160a01b031663d505accf333060208701356040880135610e4060808a0160608b01612d04565b89608001358a60a001356040518863ffffffff1660e01b8152600401610e6c9796959493929190612ca8565b600060405180830381600087803b158015610e8657600080fd5b505af1158015610e9a573d6000803e3d6000fd5b50505050610ea88686610eea565b9695505050505050565b60405163d505accf60e01b81526001600160a01b0387169063d505accf906105fe90339030908a908a908a908a908a90600401612ca8565b604080518082019091526000808252602082015282516040805160608082018352808252600060208084018290528385018290528451608081018652828152808201849052808601839052808401939093528451808601909552818552840152909160008060005b8681101561114457898181518110610f6c57610f6c612bcf565b602002602001015195508560000151600081518110610f8d57610f8d612bcf565b60200260200101519450610fae866020015186600001518860400151611773565b8551519250600091505b8282101561113c57610fcb600184612d3b565b82036110855784600001516001600160a01b0316637132bb7f866020015133886040015189606001516040518563ffffffff1660e01b81526004016110139493929190612d52565b60408051808303816000875af1158015611031573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110559190612ddb565b80516001600160a01b03168952602080820151908a018051929650909161107d908390612dfc565b90525061113c565b84600001516001600160a01b0316637132bb7f866020015133886040015189606001516040518563ffffffff1660e01b81526004016110c79493929190612d52565b60408051808303816000875af11580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111099190612ddb565b508551611117836001612dfc565b8151811061112757611127612bcf565b60200260200101519450816001019150610fb8565b600101610f52565b50878760200151101561116a5760405163c9f52c7160e01b815260040160405180910390fd5b50505050505092915050565b6040516323b872dd60e01b81526060906001600160a01b038916906323b872dd906111a99033908c908c90600401612e14565b6020604051808303816000875af11580156111c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ec9190612e4f565b5060405163f66eab5b60e01b81526001600160a01b0389169063f66eab5b906112219089903390899089908990600401612e70565b6000604051808303816000875af1158015611240573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112689190810190612f27565b805190915060005b818110156112d75786818151811061128a5761128a612bcf565b60200260200101518382815181106112a4576112a4612bcf565b60200260200101516020015110156112cf5760405163c9f52c7160e01b815260040160405180910390fd5b600101611270565b5050979650505050505050565b6040805180820182526000808252602082015290516323b872dd60e01b81526001600160a01b038816906323b872dd906113269033908b908b90600401612e14565b6020604051808303816000875af1158015611345573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113699190612e4f565b506040516313d85e7560e11b81526001600160a01b038816906327b0bcea9061139c908890339088908890600401612d52565b60408051808303816000875af11580156113ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113de9190612ddb565b90508381602001511015610ea85760405163c9f52c7160e01b815260040160405180910390fd5b600080856001600160a01b03166323b872dd86868660405160240161142c93929190612e14565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516114659190612f83565b6000604051808303816000865af19150503d80600081146114a2576040519150601f19603f3d011682016040523d82523d6000602084013e6114a7565b606091505b50915091508115806114d557508051158015906114d55750808060200190518101906114d39190612e4f565b155b15610a4c57604051631e4e7d0960e21b815260040160405180910390fd5b600080846001600160a01b031663095ea7b38585604051602401611518929190612f8f565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516115519190612f83565b6000604051808303816000865af19150503d806000811461158e576040519150601f19603f3d011682016040523d82523d6000602084013e611593565b606091505b50915091508115806115c157508051158015906115c15750808060200190518101906115bf9190612e4f565b155b156107df57604051633e3f8f7360e01b815260040160405180910390fd5b6040805180820190915260008082526020820181905290889060005b82811015611648578b8b8281811061161557611615612bcf565b90506040020180360381019061162b9190612fe8565b915061164082600001518e8460200151611773565b6001016115fb565b506040516301f3943560e11b81526001600160a01b038d16906303e7286a9061167f908c908c9033908c908c908c90600401613009565b6020604051808303816000875af115801561169e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c29190612a99565b9250868310156116e55760405163124ca15f60e11b815260040160405180910390fd5b50509998505050505050505050565b6001600160a01b03811660009081526020818152604080832033845290915290205460ff16611770576001600160a01b0381166000818152602081815260408083203384528252808320805460ff1916600190811790915580835290832080549182018155835291200180546001600160a01b03191690911790555b50565b6001600160a01b03831661181a57604051631f2c13e160e31b81526001600160a01b037f0000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b169063f9609f089083906117d19087908790600401612a73565b60206040518083038185885af11580156117ef573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906118149190612a99565b50505050565b61184683337f0000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b84611405565b604051631f2c13e160e31b81526001600160a01b037f0000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b169063f9609f08906118949086908690600401612a73565b6020604051808303816000875af11580156118b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118149190612a99565b60006001600160a01b0382165b92915050565b6118f3816118d7565b811461177057600080fd5b80356118e4816118ea565b806118f3565b80356118e481611909565b6000806040838503121561193057611930600080fd5b600061193c85856118fe565b925050602061194d8582860161190f565b9150509250929050565b611960816118d7565b82525050565b602081016118e48284611957565b634e487b7160e01b600052604160045260246000fd5b601f19601f83011681018181106001600160401b03821117156119af576119af611974565b6040525050565b60006119c160405190565b90506119cd828261198a565b919050565b60006001600160401b038211156119eb576119eb611974565b5060209081020190565b60006001600160401b03821115611a0e57611a0e611974565b601f19601f83011660200192915050565b82818337506000910152565b6000611a3e611a39846119f5565b6119b6565b905082815260208101848484011115611a5957611a59600080fd5b611a64848285611a1f565b509392505050565b600082601f830112611a8057611a80600080fd5b8135611a90848260208601611a2b565b949350505050565b600060808284031215611aad57611aad600080fd5b611ab760806119b6565b90506000611ac584846118fe565b82525060208201356001600160401b03811115611ae457611ae4600080fd5b611af084828501611a6c565b6020830152506040611b04848285016118fe565b60408301525060608201356001600160401b03811115611b2657611b26600080fd5b611b3284828501611a6c565b60608301525092915050565b6000611b4c611a39846119d2565b83815290506020808201908402830185811115611b6b57611b6b600080fd5b835b81811015611bab5780356001600160401b03811115611b8e57611b8e600080fd5b808601611b9b8982611a98565b8552505060209283019201611b6d565b5050509392505050565b600082601f830112611bc957611bc9600080fd5b8135611a90848260208601611b3e565b600060608284031215611bee57611bee600080fd5b611bf860606119b6565b905081356001600160401b03811115611c1357611c13600080fd5b611c1f84828501611bb5565b8252506020611c30848483016118fe565b6020830152506040611c448482850161190f565b60408301525092915050565b6000611c5e611a39846119d2565b83815290506020808201908402830185811115611c7d57611c7d600080fd5b835b81811015611bab5780356001600160401b03811115611ca057611ca0600080fd5b808601611cad8982611bd9565b8552505060209283019201611c7f565b600082601f830112611cd157611cd1600080fd5b8135611a90848260208601611c50565b600080600060608486031215611cf957611cf9600080fd5b83356001600160401b03811115611d1257611d12600080fd5b611d1e86828701611cbd565b9350506020611d2f8682870161190f565b9250506040611d408682870161190f565b9150509250925092565b80611960565b80516040830190611d618482611957565b5060208201516118146020850182611d4a565b604081016118e48284611d50565b60008083601f840112611d9757611d97600080fd5b5081356001600160401b03811115611db157611db1600080fd5b602083019150836001820283011115611dcc57611dcc600080fd5b9250929050565b60008083601f840112611de857611de8600080fd5b5081356001600160401b03811115611e0257611e02600080fd5b602083019150836020820283011115611dcc57611dcc600080fd5b600060608284031215611e3257611e32600080fd5b611e3c60606119b6565b90506000611e4a848461190f565b8252506020611e5b8484830161190f565b60208301525060408201356001600160401b03811115611e7d57611e7d600080fd5b611c4484828501611a6c565b60008060008060008060008060008060e08b8d031215611eab57611eab600080fd5b6000611eb78d8d6118fe565b9a50506020611ec88d828e0161190f565b99505060408b01356001600160401b03811115611ee757611ee7600080fd5b611ef38d828e01611d82565b985098505060608b01356001600160401b03811115611f1457611f14600080fd5b611f208d828e01611dd3565b96509650506080611f338d828e016118fe565b94505060a08b01356001600160401b03811115611f5257611f52600080fd5b611f5e8d828e01611d82565b935093505060c08b01356001600160401b03811115611f7f57611f7f600080fd5b611f8b8d828e01611e1d565b9150509295989b9194979a5092959850565b6000611fa98383611d50565b505060400190565b6000611fbb825190565b80845260209384019383018060005b83811015611fef578151611fde8882611f9d565b975060208301925050600101611fca565b509495945050505050565b602080825281016109be8184611fb1565b60ff81166118f3565b80356118e48161200b565b60008060008060008060c0878903121561203b5761203b600080fd5b600061204789896118fe565b965050602061205889828a0161190f565b955050604061206989828a0161190f565b945050606061207a89828a01612014565b935050608061208b89828a0161190f565b92505060a061209c89828a0161190f565b9150509295509295509295565b600080604083850312156120bf576120bf600080fd5b60006120cb85856118fe565b925050602061194d858286016118fe565b801515611960565b602081016118e482846120dc565b60008060008060008060c0878903121561210e5761210e600080fd5b600061211a89896118fe565b965050602061212b89828a0161190f565b95505060408701356001600160401b0381111561214a5761214a600080fd5b61215689828a01611a6c565b945050606061216789828a0161190f565b935050608061217889828a016118fe565b92505060a08701356001600160401b0381111561219757612197600080fd5b61209c89828a01611a6c565b600080600080608085870312156121bc576121bc600080fd5b60006121c887876118fe565b94505060206121d9878288016118fe565b93505060406121ea8782880161190f565b92505060606121fb878288016118fe565b91505092959194509250565b60008060008060006080868803121561222257612222600080fd5b600061222e88886118fe565b955050602061223f8882890161190f565b94505060406122508882890161190f565b93505060608601356001600160401b0381111561226f5761226f600080fd5b61227b88828901611d82565b92509250509295509295909350565b60008083601f84011261229f5761229f600080fd5b5081356001600160401b038111156122b9576122b9600080fd5b602083019150836040820283011115611dcc57611dcc600080fd5b600080600080600080600080600060c08a8c0312156122f5576122f5600080fd5b60006123018c8c6118fe565b99505060208a01356001600160401b0381111561232057612320600080fd5b61232c8c828d0161228a565b985098505060408a01356001600160401b0381111561234d5761234d600080fd5b6123598c828d01611d82565b9650965050606061236c8c828d0161190f565b945050608061237d8c828d016118fe565b93505060a08a01356001600160401b0381111561239c5761239c600080fd5b6123a88c828d01611d82565b92509250509295985092959850929598565b602081016118e48284611d4a565b6000606082840312156123dd576123dd600080fd5b50919050565b600080600080600080600060e0888a03121561240157612401600080fd5b600061240d8a8a6118fe565b975050602061241e8a828b0161190f565b96505060408801356001600160401b0381111561243d5761243d600080fd5b6124498a828b01611a6c565b955050606061245a8a828b0161190f565b945050608061246b8a828b016118fe565b93505060a08801356001600160401b0381111561248a5761248a600080fd5b6124968a828b01611a6c565b92505060c08801356001600160401b038111156124b5576124b5600080fd5b6124c18a828b016123c8565b91505092959891949750929550565b6000806000604084860312156124e8576124e8600080fd5b60006124f486866118fe565b93505060208401356001600160401b0381111561251357612513600080fd5b61251f86828701611d82565b92509250509250925092565b6000806020838503121561254157612541600080fd5b82356001600160401b0381111561255a5761255a600080fd5b61256685828601611dd3565b92509250509250929050565b60005b8381101561258d578181015183820152602001612575565b838111156118145750506000910152565b60006125a8825190565b8084526020840193506125bf818560208601612572565b601f19601f8201165b9093019392505050565b60006109be838361259e565b60006125e8825190565b808452602084019350836020820285016126028560200190565b8060005b85811015612637578484038952815161261f85826125d2565b94506020830160209a909a0199925050600101612606565b5091979650505050505050565b602080825281016109be81846125de565b600080600080600080600080600060c08a8c03121561267657612676600080fd5b60006126828c8c6118fe565b99505060206126938c828d0161190f565b98505060408a01356001600160401b038111156126b2576126b2600080fd5b6126be8c828d01611d82565b975097505060608a01356001600160401b038111156126df576126df600080fd5b6126eb8c828d01611dd3565b9550955050608061237d8c828d016118fe565b60006020828403121561271357612713600080fd5b6000611a9084846118fe565b600060c0828403121561273457612734600080fd5b61273e60c06119b6565b9050600061274c84846118fe565b825250602061275d8484830161190f565b60208301525060406127718482850161190f565b604083015250606061278584828501612014565b60608301525060806127998482850161190f565b60808301525060a06127ad8482850161190f565b60a08301525092915050565b60006127c7611a39846119d2565b83815290506020810160c084028301858111156127e6576127e6600080fd5b835b81811015611bab57806127fb888261271f565b84525060209092019160c0016127e8565b600082601f83011261282057612820600080fd5b8135611a908482602086016127b9565b60008060008060008060008060008060e08b8d03121561285257612852600080fd5b600061285e8d8d6118fe565b9a505060208b01356001600160401b0381111561287d5761287d600080fd5b6128898d828e0161228a565b995099505060408b01356001600160401b038111156128aa576128aa600080fd5b6128b68d828e01611d82565b975097505060606128c98d828e0161190f565b95505060806128da8d828e016118fe565b94505060a08b01356001600160401b038111156128f9576128f9600080fd5b6129058d828e01611d82565b935093505060c08b01356001600160401b0381111561292657612926600080fd5b611f8b8d828e0161280c565b600060c082840312156123dd576123dd600080fd5b600080600080610120858703121561296157612961600080fd5b84356001600160401b0381111561297a5761297a600080fd5b61298687828801611cbd565b94505060206129978782880161190f565b93505060406129a88782880161190f565b92505060606121fb87828801612932565b60a081016129c78288611957565b6129d46020830187611957565b6129e16040830186611d4a565b6129ee6060830185611d4a565b818103608083015261065a818461259e565b60ff8116611960565b6101008101612a18828b611957565b612a25602083018a611957565b612a326040830189611d4a565b612a3f6060830188611d4a565b612a4c60808301876120dc565b612a5960a0830186612a00565b612a6660c0830185611d4a565b61093a60e0830184611d4a565b60408101612a818285611957565b6109be6020830184611957565b80516118e481611909565b600060208284031215612aae57612aae600080fd5b6000611a908484612a8e565b60408101612a818285611d4a565b8183526000602084019350612ade838584611a1f565b601f19601f8401166125c8565b60a08101612af98289611957565b612b066020830188611957565b612b136040830187611d4a565b612b206060830186611d4a565b8181036080830152610910818486612ac8565b6000808335601e1936859003018112612b4e57612b4e600080fd5b8084019250823591506001600160401b03821115612b6e57612b6e600080fd5b602083019250600182023603831315612b8957612b89600080fd5b509250929050565b602080825281016109bb818486612ac8565b80516118e4816118ea565b600060208284031215612bc357612bc3600080fd5b6000611a908484612ba3565b634e487b7160e01b600052603260045260246000fd5b6000612bf2838584611a1f565b50500190565b6000611a90828486612be5565b6000612c13611a39846119f5565b905082815260208101848484011115612c2e57612c2e600080fd5b611a64848285612572565b600082601f830112612c4d57612c4d600080fd5b8151611a90848260208601612c05565b600060208284031215612c7257612c72600080fd5b81516001600160401b03811115612c8b57612c8b600080fd5b611a9084828501612c39565b602080825281016109be818461259e565b60e08101612cb6828a611957565b612cc36020830189611957565b612cd06040830188611d4a565b612cdd6060830187611d4a565b612cea6080830186612a00565b612cf760a0830185611d4a565b61091060c0830184611d4a565b600060208284031215612d1957612d19600080fd5b6000611a908484612014565b634e487b7160e01b600052601160045260246000fd5b600082821015612d4d57612d4d612d25565b500390565b60808082528101612d63818761259e565b9050612d726020830186611957565b612d7f6040830185611957565b8181036060830152610ea8818461259e565b600060408284031215612da657612da6600080fd5b612db060406119b6565b90506000612dbe8484612ba3565b8252506020612dcf84848301612a8e565b60208301525092915050565b600060408284031215612df057612df0600080fd5b6000611a908484612d91565b60008219821115612e0f57612e0f612d25565b500190565b60608101612e228286611957565b612e2f6020830185611957565b611a906040830184611d4a565b8015156118f3565b80516118e481612e3c565b600060208284031215612e6457612e64600080fd5b6000611a908484612e44565b60808082528101612e81818861259e565b9050612e906020830187611957565b612e9d6040830186611957565b818103606083015261065a818486612ac8565b6000612ebe611a39846119d2565b83815290506020810160408402830185811115612edd57612edd600080fd5b835b81811015611bab5780612ef28882612d91565b845250602090920191604001612edf565b600082601f830112612f1757612f17600080fd5b8151611a90848260208601612eb0565b600060208284031215612f3c57612f3c600080fd5b81516001600160401b03811115612f5557612f55600080fd5b611a9084828501612f03565b6000612f6b825190565b612f79818560208601612572565b9290920192915050565b60006109be8284612f61565b60408101612f9d8285611957565b6109be6020830184611d4a565b600060408284031215612fbf57612fbf600080fd5b612fc960406119b6565b90506000612fd784846118fe565b8252506020612dcf8484830161190f565b600060408284031215612ffd57612ffd600080fd5b6000611a908484612faa565b6080808252810161301b81888a612ac8565b905061302a6020830187611957565b6130376040830186611957565b8181036060830152610910818486612ac856fea264697066735822122021d6dea4e36ea46e8e3b1cdfed26aba18483ad533843a5be49c86ecbdef0e8d964736f6c634300080f0033

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

0000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f

-----Decoded View---------------
Arg [0] : _vault (address): 0x7160570BB153Edd0Ea1775EC2b2Ac9b65F1aB61B
Arg [1] : _wETH (address): 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007160570bb153edd0ea1775ec2b2ac9b65f1ab61b
Arg [1] : 000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f


Block Transaction Gas Used Reward
view all blocks sequenced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0x80e38291e06339d10AAB483C65695D004dBD5C69
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.