ETH Price: $3,060.39 (-5.52%)

Contract

0xE52180815c81D7711B83412e53259bed6a3aB70a
 
Transaction Hash
Method
Block
From
To
Value
Multicall1186981622024-04-13 7:58:2115 hrs ago1712995101IN
0xE5218081...d6a3aB70a
0 ETH0.000013070.0600621
Multicall1184528432024-04-07 15:41:036 days ago1712504463IN
0xE5218081...d6a3aB70a
0 ETH0.000002460.01108571
Multicall1183627692024-04-05 13:38:358 days ago1712324315IN
0xE5218081...d6a3aB70a
0 ETH0.000004370.0228999
Multicall1182723272024-04-03 11:23:5110 days ago1712143431IN
0xE5218081...d6a3aB70a
0 ETH0.000014450.05666758
Multicall1181374002024-03-31 8:26:1713 days ago1711873577IN
0xE5218081...d6a3aB70a
0 ETH0.0000110.05983729
Multicall1180786282024-03-29 23:47:1314 days ago1711756033IN
0xE5218081...d6a3aB70a
0 ETH0.000011680.05912065
Multicall1180545702024-03-29 10:25:1715 days ago1711707917IN
0xE5218081...d6a3aB70a
0 ETH0.00000620.03034423
Multicall1177740842024-03-22 22:35:4522 days ago1711146945IN
0xE5218081...d6a3aB70a
0 ETH0.00000140.00564685
Multicall1174406272024-03-15 5:20:3129 days ago1710480031IN
0xE5218081...d6a3aB70a
0 ETH0.00000170.00798382
Multicall1171355122024-03-08 3:50:0136 days ago1709869801IN
0xE5218081...d6a3aB70a
0 ETH0.000000050.00030364
Multicall1167017712024-02-27 2:51:5946 days ago1709002319IN
0xE5218081...d6a3aB70a
0 ETH0.000000450.00229932
Burn Liquidity1167016892024-02-27 2:49:1546 days ago1709002155IN
0xE5218081...d6a3aB70a
0 ETH0.00000030.00164966
Multicall1167016402024-02-27 2:47:3746 days ago1709002057IN
0xE5218081...d6a3aB70a
0 ETH0.000000470.00217386
Multicall1165941532024-02-24 15:04:4349 days ago1708787083IN
0xE5218081...d6a3aB70a
0 ETH0.000005550.0255093
Burn Liquidity1165881402024-02-24 11:44:1749 days ago1708775057IN
0xE5218081...d6a3aB70a
0 ETH0.000000750.00406755
Multicall1164853682024-02-22 2:38:3351 days ago1708569513IN
0xE5218081...d6a3aB70a
0 ETH0.000000590.00257844
Multicall1162972672024-02-17 18:08:3156 days ago1708193311IN
0xE5218081...d6a3aB70a
0 ETH0.000001420.005597
Multicall1160298192024-02-11 13:33:3562 days ago1707658415IN
0xE5218081...d6a3aB70a
0 ETH0.000000850.00390759
Multicall1160297912024-02-11 13:32:3962 days ago1707658359IN
0xE5218081...d6a3aB70a
0 ETH0.000000840.0038678
Multicall1155547002024-01-31 13:36:1773 days ago1706708177IN
0xE5218081...d6a3aB70a
0 ETH0.000030960.1292414
Multicall1154880322024-01-30 0:34:0174 days ago1706574841IN
0xE5218081...d6a3aB70a
0.0000477 ETH0.000023580.10005664
Multicall1153927452024-01-27 19:37:4777 days ago1706384267IN
0xE5218081...d6a3aB70a
0 ETH0.000001390.00730886
Multicall1153811142024-01-27 13:10:0577 days ago1706361005IN
0xE5218081...d6a3aB70a
0 ETH0.000001430.00577728
Burn Liquidity1152416152024-01-24 7:40:0780 days ago1706082007IN
0xE5218081...d6a3aB70a
0 ETH0.00000070.00320651
Multicall1151615462024-01-22 11:11:0982 days ago1705921869IN
0xE5218081...d6a3aB70a
0 ETH0.000000560.00237183
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
1186981622024-04-13 7:58:2115 hrs ago1712995101
0xE5218081...d6a3aB70a
0.0040612 ETH
1186981622024-04-13 7:58:2115 hrs ago1712995101
0xE5218081...d6a3aB70a
0.0040612 ETH
1184528432024-04-07 15:41:036 days ago1712504463
0xE5218081...d6a3aB70a
0.00568918 ETH
1184528432024-04-07 15:41:036 days ago1712504463
0xE5218081...d6a3aB70a
0.00568918 ETH
1183627692024-04-05 13:38:358 days ago1712324315
0xE5218081...d6a3aB70a
0.00962582 ETH
1183627692024-04-05 13:38:358 days ago1712324315
0xE5218081...d6a3aB70a
0.00962582 ETH
1182723272024-04-03 11:23:5110 days ago1712143431
0xE5218081...d6a3aB70a
0.00092349 ETH
1182723272024-04-03 11:23:5110 days ago1712143431
0xE5218081...d6a3aB70a
0.00092349 ETH
1181374002024-03-31 8:26:1713 days ago1711873577
0xE5218081...d6a3aB70a
0.01396869 ETH
1181374002024-03-31 8:26:1713 days ago1711873577
0xE5218081...d6a3aB70a
0.01396869 ETH
1180786282024-03-29 23:47:1314 days ago1711756033
0xE5218081...d6a3aB70a
0.00355813 ETH
1180786282024-03-29 23:47:1314 days ago1711756033
0xE5218081...d6a3aB70a
0.00355813 ETH
1180545702024-03-29 10:25:1715 days ago1711707917
0xE5218081...d6a3aB70a
0.0015793 ETH
1180545702024-03-29 10:25:1715 days ago1711707917
0xE5218081...d6a3aB70a
0.0015793 ETH
1174406272024-03-15 5:20:3129 days ago1710480031
0xE5218081...d6a3aB70a
0.00040379 ETH
1174406272024-03-15 5:20:3129 days ago1710480031
0xE5218081...d6a3aB70a
0.00040379 ETH
1171355122024-03-08 3:50:0136 days ago1709869801
0xE5218081...d6a3aB70a
0.00367373 ETH
1171355122024-03-08 3:50:0136 days ago1709869801
0xE5218081...d6a3aB70a
0.00367373 ETH
1167017712024-02-27 2:51:5946 days ago1709002319
0xE5218081...d6a3aB70a
0.0003004 ETH
1167017712024-02-27 2:51:5946 days ago1709002319
0xE5218081...d6a3aB70a
0.0003004 ETH
1167016402024-02-27 2:47:3746 days ago1709002057
0xE5218081...d6a3aB70a
0.00539599 ETH
1167016402024-02-27 2:47:3746 days ago1709002057
0xE5218081...d6a3aB70a
0.00539599 ETH
1165941532024-02-24 15:04:4349 days ago1708787083
0xE5218081...d6a3aB70a
0.14459137 ETH
1165941532024-02-24 15:04:4349 days ago1708787083
0xE5218081...d6a3aB70a
0.14459137 ETH
1162972672024-02-17 18:08:3156 days ago1708193311
0xE5218081...d6a3aB70a
0.01801636 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TridentRouter

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 13 : TridentRouter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

import {Multicall} from "./abstract/Multicall.sol";
import {SelfPermit} from "./abstract/SelfPermit.sol";
import {Transfer} from "./libraries/Transfer.sol";
import {IBentoBoxMinimal} from "./interfaces/IBentoBoxMinimal.sol";
import {IMasterDeployer} from "./interfaces/IMasterDeployer.sol";
import {IPool} from "./interfaces/IPool.sol";
import {ITridentRouter} from "./interfaces/ITridentRouter.sol";
import {IWETH9} from "./interfaces/IWETH9.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/// @dev Custom Errors
error NotWethSender();
error TooLittleReceived();
error NotEnoughLiquidityMinted();
error IncorrectTokenWithdrawn();
error IncorrectSlippageParams();
error InsufficientWETH();
error InvalidPool();

/// @notice Router contract that helps in swapping across Trident pools.
contract TridentRouter is ITridentRouter, SelfPermit, Multicall {
    using Transfer for address;

    /// @notice BentoBox token vault.
    IBentoBoxMinimal public immutable bento;

    /// @notice Master deployer.
    IMasterDeployer public immutable masterDeployer;

    /// @notice ERC-20 token for wrapped ETH (v9).
    address internal immutable wETH;

    /// @notice The user should use 0x0 if they want to use native currency, e.g., ETH.
    address constant USE_NATIVE = address(0);

    constructor(
        IBentoBoxMinimal _bento,
        IMasterDeployer _masterDeployer,
        address _wETH
    ) {
        bento = _bento;
        masterDeployer = _masterDeployer;
        wETH = _wETH;
        _bento.registerProtocol();
    }

    receive() external payable {
        if (msg.sender != wETH) revert NotWethSender();
    }

    /// @notice Swaps token A to token B directly. Swaps are done on `bento` tokens.
    /// @param params This includes the address of token A, pool, amount of token A to swap,
    /// minimum amount of token B after the swap and data required by the pool for the swap.
    /// @dev Ensure that the pool is trusted before calling this function. The pool can steal users' tokens.
    function exactInputSingle(ExactInputSingleParams calldata params) public payable returns (uint256 amountOut) {
        // Prefund the pool with token A.
        bento.transfer(params.tokenIn, msg.sender, params.pool, params.amountIn);
        // Trigger the swap in the pool.
        amountOut = IPool(params.pool).swap(params.data);
        // Ensure that the slippage wasn't too much. This assumes that the pool is honest.
        if (amountOut < params.amountOutMinimum) revert TooLittleReceived();
    }

    /// @notice Swaps token A to token B indirectly by using multiple hops.
    /// @param params This includes the addresses of the tokens, pools, amount of token A to swap,
    /// minimum amount of token B after the swap and data required by the pools for the swaps.
    /// @dev Ensure that the pools are trusted before calling this function. The pools can steal users' tokens.
    function exactInput(ExactInputParams calldata params) public payable returns (uint256 amountOut) {
        // Pay the first pool directly.
        bento.transfer(params.tokenIn, msg.sender, params.path[0].pool, params.amountIn);
        // Call every pool in the path.
        // Pool `N` should transfer its output tokens to pool `N+1` directly.
        // The last pool should transfer its output tokens to the user.
        // If the user wants to unwrap `wETH`, the final destination should be this contract and
        // a batch call should be made to `unwrapWETH`.
        uint256 n = params.path.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            amountOut = IPool(params.path[i].pool).swap(params.path[i].data);
        }
        // Ensure that the slippage wasn't too much. This assumes that the pool is honest.
        if (amountOut < params.amountOutMinimum) revert TooLittleReceived();
    }

    /// @notice Swaps token A to token B directly. It's the same as `exactInputSingle` except
    /// it takes raw ERC-20 tokens from the users and deposits them into `bento`.
    /// @param params This includes the address of token A, pool, amount of token A to swap,
    /// minimum amount of token B after the swap and data required by the pool for the swap.
    /// @dev Ensure that the pool is trusted before calling this function. The pool can steal users' tokens.
    function exactInputSingleWithNativeToken(ExactInputSingleParams calldata params) public payable returns (uint256 amountOut) {
        // Deposits the native ERC-20 token from the user into the pool's `bento`.
        _depositToBentoBox(params.tokenIn, params.pool, params.amountIn);
        // Trigger the swap in the pool.
        amountOut = IPool(params.pool).swap(params.data);
        // Ensure that the slippage wasn't too much. This assumes that the pool is honest.
        if (amountOut < params.amountOutMinimum) revert TooLittleReceived();
    }

    /// @notice Swaps token A to token B indirectly by using multiple hops. It's the same as `exactInput` except
    /// it takes raw ERC-20 tokens from the users and deposits them into `bento`.
    /// @param params This includes the addresses of the tokens, pools, amount of token A to swap,
    /// minimum amount of token B after the swap and data required by the pools for the swaps.
    /// @dev Ensure that the pools are trusted before calling this function. The pools can steal users' tokens.
    function exactInputWithNativeToken(ExactInputParams calldata params) public payable returns (uint256 amountOut) {
        // Deposits the native ERC-20 token from the user into the pool's `bento`.
        _depositToBentoBox(params.tokenIn, params.path[0].pool, params.amountIn);
        // Call every pool in the path.
        // Pool `N` should transfer its output tokens to pool `N+1` directly.
        // The last pool should transfer its output tokens to the user.
        uint256 n = params.path.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            amountOut = IPool(params.path[i].pool).swap(params.path[i].data);
        }
        // Ensure that the slippage wasn't too much. This assumes that the pool is honest.
        if (amountOut < params.amountOutMinimum) revert TooLittleReceived();
    }

    /// @notice Swaps multiple input tokens to multiple output tokens using multiple paths, in different percentages.
    /// For example, you can swap 50 DAI + 100 USDC into 60% ETH and 40% BTC.
    /// @param params This includes everything needed for the swap. Look at the `ComplexPathParams` struct for more details.
    /// @dev This function is not optimized for single swaps and should only be used in complex cases where
    /// the amounts are large enough that minimizing slippage by using multiple paths is worth the extra gas.
    function complexPath(ComplexPathParams calldata params) public payable {
        // Deposit all initial tokens to respective pools and initiate the swaps.
        // Input tokens come from the user - output goes to following pools.
        uint256 n = params.initialPath.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            if (params.initialPath[i].native) {
                _depositToBentoBox(params.initialPath[i].tokenIn, params.initialPath[i].pool, params.initialPath[i].amount);
            } else {
                bento.transfer(params.initialPath[i].tokenIn, msg.sender, params.initialPath[i].pool, params.initialPath[i].amount);
            }
            IPool(params.initialPath[i].pool).swap(params.initialPath[i].data);
        }
        // Do all the middle swaps. Input comes from previous pools.
        n = params.percentagePath.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            uint256 balanceShares = bento.balanceOf(params.percentagePath[i].tokenIn, address(this));
            uint256 transferShares = (balanceShares * params.percentagePath[i].balancePercentage) / uint256(10)**8;
            bento.transfer(params.percentagePath[i].tokenIn, address(this), params.percentagePath[i].pool, transferShares);
            IPool(params.percentagePath[i].pool).swap(params.percentagePath[i].data);
        }
        // Ensure enough was received and transfer the ouput to the recipient.
        n = params.output.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            uint256 balanceShares = bento.balanceOf(params.output[i].token, address(this));
            if (balanceShares < params.output[i].minAmount) revert TooLittleReceived();
            if (params.output[i].unwrapBento) {
                bento.withdraw(params.output[i].token, address(this), params.output[i].to, 0, balanceShares);
            } else {
                bento.transfer(params.output[i].token, address(this), params.output[i].to, balanceShares);
            }
        }
    }

    /// @notice Add liquidity to a pool.
    /// @param tokenInput Token address and amount to add as liquidity.
    /// @param pool Pool address to add liquidity to.
    /// @param minLiquidity Minimum output liquidity - caps slippage.
    /// @param data Data required by the pool to add liquidity.
    function addLiquidity(
        TokenInput[] calldata tokenInput,
        address pool,
        uint256 minLiquidity,
        bytes calldata data
    ) public payable returns (uint256 liquidity) {
        // Send all input tokens to the pool.
        uint256 n = tokenInput.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            if (tokenInput[i].native) {
                _depositToBentoBox(tokenInput[i].token, pool, tokenInput[i].amount);
            } else {
                bento.transfer(tokenInput[i].token, msg.sender, pool, tokenInput[i].amount);
            }
        }
        liquidity = IPool(pool).mint(data);
        if (liquidity < minLiquidity) revert NotEnoughLiquidityMinted();
    }

    /// @notice Burn liquidity tokens to get back `bento` tokens.
    /// @param pool Pool address.
    /// @param liquidity Amount of liquidity tokens to burn.
    /// @param data Data required by the pool to burn liquidity.
    /// @param minWithdrawals Minimum amount of `bento` tokens to be returned.
    function burnLiquidity(
        address pool,
        uint256 liquidity,
        bytes calldata data,
        IPool.TokenAmount[] calldata minWithdrawals
    ) public payable {
        pool.safeTransferFrom(msg.sender, pool, liquidity);
        IPool.TokenAmount[] memory withdrawnLiquidity = IPool(pool).burn(data);
        uint256 n = minWithdrawals.length;
        for (uint256 i = 0; i < n; i = _increment(i)) {
            if (minWithdrawals[i].token != withdrawnLiquidity[i].token) revert IncorrectSlippageParams();
            if (withdrawnLiquidity[i].amount < minWithdrawals[i].amount) revert TooLittleReceived();
        }
    }

    /// @notice Burn liquidity tokens to get back `bento` tokens.
    /// @dev The tokens are swapped automatically and the output is in a single token.
    /// @param pool Pool address.
    /// @param liquidity Amount of liquidity tokens to burn.
    /// @param data Data required by the pool to burn liquidity.
    /// @param minWithdrawal Minimum amount of tokens to be returned.
    function burnLiquiditySingle(
        address pool,
        uint256 liquidity,
        bytes calldata data,
        uint256 minWithdrawal
    ) public payable {
        // Use 'liquidity = 0' for prefunding.
        pool.safeTransferFrom(msg.sender, pool, liquidity);
        uint256 withdrawn = IPool(pool).burnSingle(data);
        if (withdrawn < minWithdrawal) revert TooLittleReceived();
    }

    /// @notice Recover mistakenly sent tokens.
    function sweep(
        address token,
        address recipient,
        bool fromBento
    ) external payable {
        if (fromBento) {
            uint256 shares = bento.balanceOf(token, address(this));
            bento.transfer(token, address(this), recipient, shares);
        } else {
            uint256 amount = token == USE_NATIVE ? address(this).balance : (IERC20(token).balanceOf(address(this)) - 1);
            token == USE_NATIVE ? recipient.safeTransferETH(amount) : token.safeTransfer(recipient, amount);
        }
    }

    /// @notice Unwrap this contract's wETH into ETH.
    function unwrapWETH(address recipient) external payable {
        uint256 balance = IWETH9(wETH).balanceOf(address(this));
        IWETH9(wETH).withdraw(balance);
        recipient.safeTransferETH(balance);
    }

    /// @notice Wrapper function to allow pool deployment to be batched.
    function deployPool(address factory, bytes calldata deployData) external payable returns (address) {
        return masterDeployer.deployPool(factory, deployData);
    }

    /// @notice Wrapper function to allow bento set master contract approval to be batched, so the first trade can happen in one transaction.
    function approveMasterContract(
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable {
        bento.setMasterContractApproval(msg.sender, address(this), true, v, r, s);
    }

    /// @notice Call BentoBox harvest function to rebalance a BentoBox token strategy and ensure there are enough tokens available to withdraw a swap output.
    /// @dev Should be batched in before a swap.
    function harvest(address token, uint256 maxChangeAmount) external payable {
        bento.harvest(token, true, maxChangeAmount);
    }

    /// @notice Deposit from the user's wallet into BentoBox.
    /// @dev Amount is the native token amount. We let BentoBox do the conversion into shares.
    function _depositToBentoBox(
        address token,
        address recipient,
        uint256 amount
    ) internal {
        bento.deposit{value: token == USE_NATIVE ? amount : 0}(token, msg.sender, recipient, amount, 0);
    }

    function _increment(uint256 i) internal pure returns (uint256) {
        unchecked {
            return i + 1;
        }
    }
}

File 2 of 13 : SelfPermit.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol";

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

abstract contract SelfPermit {
    function selfPermit(
        address token,
        uint256 value,
        uint256 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,
        uint256 value,
        uint256 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);
    }
}

File 3 of 13 : 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 (uint256 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;
            }
        }
    }
}

File 4 of 13 : Transfer.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

library Transfer {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "STF");
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "ST");
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SA");
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "STE");
    }
}

File 5 of 13 : IBentoBoxMinimal.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

import "../libraries/RebaseLibrary.sol";

/// @notice Minimal BentoBox vault interface.
/// @dev `token` is aliased as `address` from `IERC20` for simplicity.
interface IBentoBoxMinimal {
    /// @notice Balance per ERC-20 token per account in shares.
    function balanceOf(address, address) external view returns (uint256);

    /// @dev Helper function to represent an `amount` of `token` in shares.
    /// @param token The ERC-20 token.
    /// @param amount The `token` amount.
    /// @param roundUp If the result `share` should be rounded up.
    /// @return share The token amount represented in shares.
    function toShare(
        address token,
        uint256 amount,
        bool roundUp
    ) external view returns (uint256 share);

    /// @dev Helper function to represent shares back into the `token` amount.
    /// @param token The ERC-20 token.
    /// @param share The amount of shares.
    /// @param roundUp If the result should be rounded up.
    /// @return amount The share amount back into native representation.
    function toAmount(
        address token,
        uint256 share,
        bool roundUp
    ) external view returns (uint256 amount);

    /// @notice Registers this contract so that users can approve it for BentoBox.
    function registerProtocol() external;

    /// @notice Deposit an amount of `token` represented in either `amount` or `share`.
    /// @param token The ERC-20 token to deposit.
    /// @param from which account to pull the tokens.
    /// @param to which account to push the tokens.
    /// @param amount Token amount in native representation to deposit.
    /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`.
    /// @return amountOut The amount deposited.
    /// @return shareOut The deposited amount represented in shares.
    function deposit(
        address token,
        address from,
        address to,
        uint256 amount,
        uint256 share
    ) external payable returns (uint256 amountOut, uint256 shareOut);

    /// @notice Withdraws an amount of `token` from a user account.
    /// @param token_ The ERC-20 token to withdraw.
    /// @param from which user to pull the tokens.
    /// @param to which user to push the tokens.
    /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.
    /// @param share Like above, but `share` takes precedence over `amount`.
    function withdraw(
        address token_,
        address from,
        address to,
        uint256 amount,
        uint256 share
    ) external returns (uint256 amountOut, uint256 shareOut);

    /// @notice Transfer shares from a user account to another one.
    /// @param token The ERC-20 token to transfer.
    /// @param from which user to pull the tokens.
    /// @param to which user to push the tokens.
    /// @param share The amount of `token` in shares.
    function transfer(
        address token,
        address from,
        address to,
        uint256 share
    ) external;

    /// @dev Reads the Rebase `totals`from storage for a given token
    function totals(address token) external view returns (Rebase memory total);

    /// @dev Approves users' BentoBox assets to a "master" contract.
    function setMasterContractApproval(
        address user,
        address masterContract,
        bool approved,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    function harvest(
        address token,
        bool balance,
        uint256 maxChangeAmount
    ) external;
}

File 6 of 13 : ITridentRouter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

/// @notice Trident pool router interface.
interface ITridentRouter {
    struct Path {
        address pool;
        bytes data;
    }

    struct ExactInputSingleParams {
        uint256 amountIn;
        uint256 amountOutMinimum;
        address pool;
        address tokenIn;
        bytes data;
    }

    struct ExactInputParams {
        address tokenIn;
        uint256 amountIn;
        uint256 amountOutMinimum;
        Path[] path;
    }

    struct TokenInput {
        address token;
        bool native;
        uint256 amount;
    }

    struct InitialPath {
        address tokenIn;
        address pool;
        bool native;
        uint256 amount;
        bytes data;
    }

    struct PercentagePath {
        address tokenIn;
        address pool;
        uint64 balancePercentage; // Multiplied by 10^6. 100% = 100_000_000
        bytes data;
    }

    struct Output {
        address token;
        address to;
        bool unwrapBento;
        uint256 minAmount;
    }

    struct ComplexPathParams {
        InitialPath[] initialPath;
        PercentagePath[] percentagePath;
        Output[] output;
    }
}

File 7 of 13 : IMasterDeployer.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

/// @notice Trident pool deployer interface.
interface IMasterDeployer {
    function barFee() external view returns (uint256);

    function barFeeTo() external view returns (address);

    function bento() external view returns (address);

    function migrator() external view returns (address);

    function pools(address pool) external view returns (bool);

    function deployPool(address factory, bytes calldata deployData) external returns (address);
}

File 8 of 13 : IPool.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;

/// @notice Trident pool interface.
interface IPool {
    /// @notice Executes a swap from one token to another.
    /// @dev The input tokens must've already been sent to the pool.
    /// @param data ABI-encoded params that the pool requires.
    /// @return finalAmountOut The amount of output tokens that were sent to the user.
    function swap(bytes calldata data) external returns (uint256 finalAmountOut);

    /// @notice Executes a swap from one token to another with a callback.
    /// @dev This function allows borrowing the output tokens and sending the input tokens in the callback.
    /// @param data ABI-encoded params that the pool requires.
    /// @return finalAmountOut The amount of output tokens that were sent to the user.
    function flashSwap(bytes calldata data) external returns (uint256 finalAmountOut);

    /// @notice Mints liquidity tokens.
    /// @param data ABI-encoded params that the pool requires.
    /// @return liquidity The amount of liquidity tokens that were minted for the user.
    function mint(bytes calldata data) external returns (uint256 liquidity);

    /// @notice Burns liquidity tokens.
    /// @dev The input LP tokens must've already been sent to the pool.
    /// @param data ABI-encoded params that the pool requires.
    /// @return withdrawnAmounts The amount of various output tokens that were sent to the user.
    function burn(bytes calldata data) external returns (TokenAmount[] memory withdrawnAmounts);

    /// @notice Burns liquidity tokens for a single output token.
    /// @dev The input LP tokens must've already been sent to the pool.
    /// @param data ABI-encoded params that the pool requires.
    /// @return amountOut The amount of output tokens that were sent to the user.
    function burnSingle(bytes calldata data) external returns (uint256 amountOut);

    /// @return A unique identifier for the pool type.
    function poolIdentifier() external pure returns (bytes32);

    /// @return An array of tokens supported by the pool.
    function getAssets() external view returns (address[] memory);

    /// @notice Simulates a trade and returns the expected output.
    /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.
    /// @param data ABI-encoded params that the pool requires.
    /// @return finalAmountOut The amount of output tokens that will be sent to the user if the trade is executed.
    function getAmountOut(bytes calldata data) external view returns (uint256 finalAmountOut);

    /// @notice Simulates a trade and returns the expected output.
    /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.
    /// @param data ABI-encoded params that the pool requires.
    /// @return finalAmountIn The amount of input tokens that are required from the user if the trade is executed.
    function getAmountIn(bytes calldata data) external view returns (uint256 finalAmountIn);

    /// @dev This event must be emitted on all swaps.
    event Swap(address indexed recipient, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut);

    /// @dev This struct frames output tokens for burns.
    struct TokenAmount {
        address token;
        uint256 amount;
    }
}

File 9 of 13 : IWETH9.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IWETH9 is IERC20 {
    function deposit() external payable;
    function withdraw(uint256) external;
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 11 of 13 : IERC20PermitAllowed.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

interface IERC20PermitAllowed {
    function permit(
        address holder,
        address spender,
        uint256 nonce,
        uint256 expiry,
        bool allowed,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

File 12 of 13 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 13 of 13 : RebaseLibrary.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity ^0.8;

struct Rebase {
    uint128 elastic;
    uint128 base;
}

/// @notice A rebasing library
library RebaseLibrary {
    /// @notice Calculates the base value in relationship to `elastic` and `total`.
    function toBase(Rebase memory total, uint256 elastic) internal pure returns (uint256 base) {
        if (total.elastic == 0) {
            base = elastic;
        } else {
            base = (elastic * total.base) / total.elastic;
        }
    }

    /// @notice Calculates the elastic value in relationship to `base` and `total`.
    function toElastic(Rebase memory total, uint256 base) internal pure returns (uint256 elastic) {
        if (total.base == 0) {
            elastic = base;
        } else {
            elastic = (base * total.elastic) / total.base;
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IBentoBoxMinimal","name":"_bento","type":"address"},{"internalType":"contract IMasterDeployer","name":"_masterDeployer","type":"address"},{"internalType":"address","name":"_wETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"IncorrectSlippageParams","type":"error"},{"inputs":[],"name":"NotEnoughLiquidityMinted","type":"error"},{"inputs":[],"name":"NotWethSender","type":"error"},{"inputs":[],"name":"TooLittleReceived","type":"error"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"native","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITridentRouter.TokenInput[]","name":"tokenInput","type":"tuple[]"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"approveMasterContract","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bento","outputs":[{"internalType":"contract IBentoBoxMinimal","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount[]","name":"minWithdrawals","type":"tuple[]"}],"name":"burnLiquidity","outputs":[],"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":"minWithdrawal","type":"uint256"}],"name":"burnLiquiditySingle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"bool","name":"native","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITridentRouter.InitialPath[]","name":"initialPath","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint64","name":"balancePercentage","type":"uint64"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITridentRouter.PercentagePath[]","name":"percentagePath","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"unwrapBento","type":"bool"},{"internalType":"uint256","name":"minAmount","type":"uint256"}],"internalType":"struct ITridentRouter.Output[]","name":"output","type":"tuple[]"}],"internalType":"struct ITridentRouter.ComplexPathParams","name":"params","type":"tuple"}],"name":"complexPath","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"factory","type":"address"},{"internalType":"bytes","name":"deployData","type":"bytes"}],"name":"deployPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITridentRouter.Path[]","name":"path","type":"tuple[]"}],"internalType":"struct ITridentRouter.ExactInputParams","name":"params","type":"tuple"}],"name":"exactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITridentRouter.ExactInputSingleParams","name":"params","type":"tuple"}],"name":"exactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITridentRouter.ExactInputSingleParams","name":"params","type":"tuple"}],"name":"exactInputSingleWithNativeToken","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITridentRouter.Path[]","name":"path","type":"tuple[]"}],"internalType":"struct ITridentRouter.ExactInputParams","name":"params","type":"tuple"}],"name":"exactInputWithNativeToken","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxChangeAmount","type":"uint256"}],"name":"harvest","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"masterDeployer","outputs":[{"internalType":"contract IMasterDeployer","name":"","type":"address"}],"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":"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":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"fromBento","type":"bool"}],"name":"sweep","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"unwrapWETH","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040523480156200001157600080fd5b5060405162003a4c38038062003a4c8339810160408190526200003491620000c3565b6001600160a01b03808416608081905283821660a05290821660c0526040805163577268d960e11b8152905163aee4d1b29160048082019260009290919082900301818387803b1580156200008857600080fd5b505af11580156200009d573d6000803e3d6000fd5b5050505050505062000117565b6001600160a01b0381168114620000c057600080fd5b50565b600080600060608486031215620000d957600080fd5b8351620000e681620000aa565b6020850151909350620000f981620000aa565b60408501519092506200010c81620000aa565b809150509250925092565b60805160a05160c05161388e620001be600039600081816101800152818161152901526115db0152600081816103ac015261095a0152600081816102d30152818161043401528181610669015281816109f701528181610caf01528181610f000152818161129f0152818161136901528181611a0f01528181611ca201528181611e1e01528181612099015281816122370152818161238f01526125f6015261388e6000f3fe6080604052600436106101635760003560e01c8063783312d9116100c0578063ac9650d811610074578063c2e3140a11610059578063c2e3140a14610387578063cf58879a1461039a578063f3995c67146103ce57600080fd5b8063ac9650d814610354578063b96c5c0e1461037457600080fd5b806389a3f136116100a557806389a3f1361461031b5780639fa744911461032e578063a4a78f0c1461034157600080fd5b8063783312d9146102f55780637f6ad4551461030857600080fd5b80632c0d9a0111610117578063403335a8116100fc578063403335a81461029b5780634659a494146102ae5780634da31827146102c157600080fd5b80632c0d9a01146102755780632cfcb94f1461028857600080fd5b80630f93d439116101485780630f93d439146102175780631aa349a81461022a578063250558dc1461023d57600080fd5b8063018ee9b7146101de5780630b0d1b1e146101f157600080fd5b366101d9573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101d7576040517fe7218bb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b005b600080fd5b6101d76101ec366004612acc565b6103e1565b6102046101ff366004612af8565b610494565b6040519081526020015b60405180910390f35b610204610225366004612b3a565b610650565b6101d7610238366004612bbe565b610822565b61025061024b366004612c22565b61091a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161020e565b610204610283366004612af8565b6109de565b610204610296366004612c77565b610c1f565b6101d76102a9366004612d43565b610eae565b6101d76102bc366004612d76565b610f76565b3480156102cd57600080fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6101d7610303366004612dd0565b611031565b6101d7610316366004612e99565b61124b565b6101d7610329366004612ee4565b6114f8565b61020461033c366004612b3a565b611671565b6101d761034f366004612d76565b6116ad565b610367610362366004612f01565b611777565b60405161020e9190612fec565b6101d761038236600461306c565b6118e7565b6101d7610395366004612d76565b6124bc565b3480156103a657600080fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6101d76103dc366004612d76565b612562565b6040517f66c6bb0b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260016024830152604482018390527f000000000000000000000000000000000000000000000000000000000000000016906366c6bb0b90606401600060405180830381600087803b15801561047857600080fd5b505af115801561048c573d6000803e3d6000fd5b505050505050565b60006104ee6104a66020840184612ee4565b6104b360608501856130a7565b60008181106104c4576104c461310f565b90506020028101906104d6919061313e565b6104e4906020810190612ee4565b84602001356125df565b60006104fd60608401846130a7565b9050905060005b8181101561060b5761051960608501856130a7565b828181106105295761052961310f565b905060200281019061053b919061313e565b610549906020810190612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a61057160608701876130a7565b848181106105815761058161310f565b9050602002810190610593919061313e565b6105a190602081019061317c565b6040518363ffffffff1660e01b81526004016105be92919061322a565b6020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610601919061323e565b9250600101610504565b50826040013582101561064a576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f18d03cc61069e6080850160608601612ee4565b336106af6060870160408801612ee4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015284356064820152608401600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50610755925050506060830160408401612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a61077d608085018561317c565b6040518363ffffffff1660e01b815260040161079a92919061322a565b6020604051808303816000875af11580156107b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dd919061323e565b9050816020013581101561081d576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b61084473ffffffffffffffffffffffffffffffffffffffff86163387876126de565b6040517faf8c09bf00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff87169063af8c09bf9061089b908790879060040161322a565b6020604051808303816000875af11580156108ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108de919061323e565b90508181101561048c576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f250558dc00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063250558dc9061099390879087908790600401613257565b6020604051808303816000875af11580156109b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d69190613290565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f18d03cc610a296020850185612ee4565b33610a3760608701876130a7565b6000818110610a4857610a4861310f565b9050602002810190610a5a919061313e565b610a68906020810190612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015260208501356064820152608401600060405180830381600087803b158015610ae857600080fd5b505af1158015610afc573d6000803e3d6000fd5b5060009250610b1191505060608401846130a7565b9050905060005b8181101561060b57610b2d60608501856130a7565b82818110610b3d57610b3d61310f565b9050602002810190610b4f919061313e565b610b5d906020810190612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a610b8560608701876130a7565b84818110610b9557610b9561310f565b9050602002810190610ba7919061313e565b610bb590602081019061317c565b6040518363ffffffff1660e01b8152600401610bd292919061322a565b6020604051808303816000875af1158015610bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c15919061323e565b9250600101610b18565b600085815b81811015610dcf57888882818110610c3e57610c3e61310f565b9050606002016020016020810190610c5691906132ad565b15610cad57610ca8898983818110610c7057610c7061310f565b610c869260206060909202019081019150612ee4565b888b8b85818110610c9957610c9961310f565b905060600201604001356125df565b610dc7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f18d03cc8a8a84818110610cfb57610cfb61310f565b610d119260206060909202019081019150612ee4565b338a8d8d87818110610d2557610d2561310f565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e08a901b16815273ffffffffffffffffffffffffffffffffffffffff978816600482015295871660248701529590931660448501525060609091020191909101356064820152608401600060405180830381600087803b158015610dae57600080fd5b505af1158015610dc2573d6000803e3d6000fd5b505050505b600101610c24565b506040517f7ba0e2e700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871690637ba0e2e790610e24908790879060040161322a565b6020604051808303816000875af1158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e67919061323e565b915084821015610ea3576040517f249942be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509695505050505050565b6040517fc0a47c930000000000000000000000000000000000000000000000000000000081523360048201523060248201526001604482015260ff841660648201526084810183905260a481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c0a47c939060c401600060405180830381600087803b158015610f5957600080fd5b505af1158015610f6d573d6000803e3d6000fd5b50505050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b600060405180830381600087803b15801561101157600080fd5b505af1158015611025573d6000803e3d6000fd5b50505050505050505050565b61105373ffffffffffffffffffffffffffffffffffffffff87163388886126de565b6040517f2a07b6c700000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff881690632a07b6c7906110aa908890889060040161322a565b6000604051808303816000875af11580156110c9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110f9190810190613371565b90508160005b818110156112405782818151811061112f5761112f61310f565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168585838181106111635761116361310f565b6111799260206040909202019081019150612ee4565b73ffffffffffffffffffffffffffffffffffffffff16146111c6576040517f2664ab9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484828181106111d8576111d861310f565b905060400201602001358382815181106111f4576111f461310f565b6020026020010151602001511015611238576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611115565b505050505050505050565b80156113cd576040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301523060248301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f7888aec90604401602060405180830381865afa1580156112e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130c919061323e565b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301523060248301528581166044830152606482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063f18d03cc90608401600060405180830381600087803b1580156113af57600080fd5b505af11580156113c3573d6000803e3d6000fd5b5050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff84161561148b576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260019073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015611458573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147c919061323e565b6114869190613476565b61148d565b475b905073ffffffffffffffffffffffffffffffffffffffff8416156114d1576114cc73ffffffffffffffffffffffffffffffffffffffff8516848361284f565b6114f1565b6114f173ffffffffffffffffffffffffffffffffffffffff8416826129b8565b505b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a9919061323e565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561163457600080fd5b505af1158015611648573d6000803e3d6000fd5b5061166d9250505073ffffffffffffffffffffffffffffffffffffffff8316826129b8565b5050565b600061169d6116866080840160608501612ee4565b6116966060850160408601612ee4565b84356125df565b6107556060830160408401612ee4565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611763919061323e565b101561048c5761048c868686868686610f76565b60608167ffffffffffffffff811115611792576117926132ca565b6040519080825280602002602001820160405280156117c557816020015b60608152602001906001900390816117b05790505b50905060005b828110156118e057600080308686858181106117e9576117e961310f565b90506020028101906117fb919061317c565b60405161180992919061348d565b600060405180830381855af49150503d8060008114611844576040519150601f19603f3d011682016040523d82523d6000602084013e611849565b606091505b5091509150816118b85760448151101561186257600080fd5b6004810190508080602001905181019061187c919061349d565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118af919061354f565b60405180910390fd5b808484815181106118cb576118cb61310f565b602090810291909101015250506001016117cb565b5092915050565b60006118f382806130a7565b9050905060005b81811015611c6c5761190c83806130a7565b8281811061191c5761191c61310f565b905060200281019061192e9190613562565b61193f9060608101906040016132ad565b156119f8576119f361195184806130a7565b838181106119615761196161310f565b90506020028101906119739190613562565b611981906020810190612ee4565b61198b85806130a7565b8481811061199b5761199b61310f565b90506020028101906119ad9190613562565b6119be906040810190602001612ee4565b6119c886806130a7565b858181106119d8576119d861310f565b90506020028101906119ea9190613562565b606001356125df565b611b71565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f18d03cc611a3e85806130a7565b84818110611a4e57611a4e61310f565b9050602002810190611a609190613562565b611a6e906020810190612ee4565b33611a7987806130a7565b86818110611a8957611a8961310f565b9050602002810190611a9b9190613562565b611aac906040810190602001612ee4565b611ab688806130a7565b87818110611ac657611ac661310f565b9050602002810190611ad89190613562565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff94851660048201529284166024840152921660448201526060909101356064820152608401600060405180830381600087803b158015611b5857600080fd5b505af1158015611b6c573d6000803e3d6000fd5b505050505b611b7b83806130a7565b82818110611b8b57611b8b61310f565b9050602002810190611b9d9190613562565b611bae906040810190602001612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a611bd385806130a7565b84818110611be357611be361310f565b9050602002810190611bf59190613562565b611c0390608081019061317c565b6040518363ffffffff1660e01b8152600401611c2092919061322a565b6020604051808303816000875af1158015611c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c63919061323e565b506001016118fa565b50611c7a60208301836130a7565b9050905060005b8181101561206357600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f7888aec611cd460208701876130a7565b85818110611ce457611ce461310f565b9050602002810190611cf69190613596565b611d04906020810190612ee4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015611d73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d97919061323e565b90506000611da76008600a6136ec565b611db460208701876130a7565b85818110611dc457611dc461310f565b9050602002810190611dd69190613596565b611de79060608101906040016136fb565b611dfb9067ffffffffffffffff1684613725565b611e059190613762565b905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f18d03cc611e5060208801886130a7565b86818110611e6057611e6061310f565b9050602002810190611e729190613596565b611e80906020810190612ee4565b30611e8e60208a018a6130a7565b88818110611e9e57611e9e61310f565b9050602002810190611eb09190613596565b611ec1906040810190602001612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015260648101849052608401600060405180830381600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b50611f649250505060208601866130a7565b84818110611f7457611f7461310f565b9050602002810190611f869190613596565b611f97906040810190602001612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a611fbf60208801886130a7565b86818110611fcf57611fcf61310f565b9050602002810190611fe19190613596565b611fef90606081019061317c565b6040518363ffffffff1660e01b815260040161200c92919061322a565b6020604051808303816000875af115801561202b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204f919061323e565b50505061205c8160010190565b9050611c81565b50612071604083018361379d565b9050905060005b818110156114f357600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f7888aec6120cb604087018761379d565b858181106120db576120db61310f565b6120f19260206080909202019081019150612ee4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015612160573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612184919061323e565b9050612193604085018561379d565b838181106121a3576121a361310f565b905060800201606001358110156121e6576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121f3604085018561379d565b838181106122035761220361310f565b905060800201604001602081019061221b91906132ad565b156123785773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166397da6d30612269604087018761379d565b858181106122795761227961310f565b61228f9260206080909202019081019150612ee4565b3061229d604089018961379d565b878181106122ad576122ad61310f565b90506080020160200160208101906122c59190612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529091166044820152600060648201526084810184905260a40160408051808303816000875af115801561234d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123719190613805565b50506124b3565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f18d03cc6123c1604087018761379d565b858181106123d1576123d161310f565b6123e79260206080909202019081019150612ee4565b306123f5604089018961379d565b878181106124055761240561310f565b905060800201602001602081019061241d9190612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015260648101849052608401600060405180830381600087803b15801561249a57600080fd5b505af11580156124ae573d6000803e3d6000fd5b505050505b50600101612078565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa15801561252e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612552919061323e565b101561048c5761048c8686868686865b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e401610ff7565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116906302b9446c9085161561262c57600061262e565b825b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff808816600483015233602483015286166044820152606481018590526000608482015260a401604080518083038185885af11580156126b2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906126d79190613805565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161277d9190613829565b6000604051808303816000865af19150503d80600081146127ba576040519150601f19603f3d011682016040523d82523d6000602084013e6127bf565b606091505b50915091508180156127e95750805115806127e95750808060200190518101906127e9919061383b565b61048c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f535446000000000000000000000000000000000000000000000000000000000060448201526064016118af565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916128e69190613829565b6000604051808303816000865af19150503d8060008114612923576040519150601f19603f3d011682016040523d82523d6000602084013e612928565b606091505b5091509150818015612952575080511580612952575080806020019051810190612952919061383b565b6126d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064016118af565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516129ef9190613829565b60006040518083038185875af1925050503d8060008114612a2c576040519150601f19603f3d011682016040523d82523d6000602084013e612a31565b606091505b50509050806114f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f535445000000000000000000000000000000000000000000000000000000000060448201526064016118af565b73ffffffffffffffffffffffffffffffffffffffff81168114612abe57600080fd5b50565b803561081d81612a9c565b60008060408385031215612adf57600080fd5b8235612aea81612a9c565b946020939093013593505050565b600060208284031215612b0a57600080fd5b813567ffffffffffffffff811115612b2157600080fd5b820160808185031215612b3357600080fd5b9392505050565b600060208284031215612b4c57600080fd5b813567ffffffffffffffff811115612b6357600080fd5b820160a08185031215612b3357600080fd5b60008083601f840112612b8757600080fd5b50813567ffffffffffffffff811115612b9f57600080fd5b602083019150836020828501011115612bb757600080fd5b9250929050565b600080600080600060808688031215612bd657600080fd5b8535612be181612a9c565b945060208601359350604086013567ffffffffffffffff811115612c0457600080fd5b612c1088828901612b75565b96999598509660600135949350505050565b600080600060408486031215612c3757600080fd5b8335612c4281612a9c565b9250602084013567ffffffffffffffff811115612c5e57600080fd5b612c6a86828701612b75565b9497909650939450505050565b60008060008060008060808789031215612c9057600080fd5b863567ffffffffffffffff80821115612ca857600080fd5b818901915089601f830112612cbc57600080fd5b813581811115612ccb57600080fd5b8a6020606083028501011115612ce057600080fd5b60208301985080975050612cf660208a01612ac1565b9550604089013594506060890135915080821115612d1357600080fd5b50612d2089828a01612b75565b979a9699509497509295939492505050565b803560ff8116811461081d57600080fd5b600080600060608486031215612d5857600080fd5b612d6184612d32565b95602085013595506040909401359392505050565b60008060008060008060c08789031215612d8f57600080fd5b8635612d9a81612a9c565b95506020870135945060408701359350612db660608801612d32565b92506080870135915060a087013590509295509295509295565b60008060008060008060808789031215612de957600080fd5b8635612df481612a9c565b955060208701359450604087013567ffffffffffffffff80821115612e1857600080fd5b612e248a838b01612b75565b90965094506060890135915080821115612e3d57600080fd5b818901915089601f830112612e5157600080fd5b813581811115612e6057600080fd5b8a60208260061b8501011115612e7557600080fd5b6020830194508093505050509295509295509295565b8015158114612abe57600080fd5b600080600060608486031215612eae57600080fd5b8335612eb981612a9c565b92506020840135612ec981612a9c565b91506040840135612ed981612e8b565b809150509250925092565b600060208284031215612ef657600080fd5b8135612b3381612a9c565b60008060208385031215612f1457600080fd5b823567ffffffffffffffff80821115612f2c57600080fd5b818501915085601f830112612f4057600080fd5b813581811115612f4f57600080fd5b8660208260051b8501011115612f6457600080fd5b60209290920196919550909350505050565b60005b83811015612f91578181015183820152602001612f79565b838111156114f15750506000910152565b60008151808452612fba816020860160208601612f76565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561305f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261304d858351612fa2565b94509285019290850190600101613013565b5092979650505050505050565b60006020828403121561307e57600080fd5b813567ffffffffffffffff81111561309557600080fd5b820160608185031215612b3357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126130dc57600080fd5b83018035915067ffffffffffffffff8211156130f757600080fd5b6020019150600581901b3603821315612bb757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261317257600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126131b157600080fd5b83018035915067ffffffffffffffff8211156131cc57600080fd5b602001915036819003821315612bb757600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006109d66020830184866131e1565b60006020828403121561325057600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006132876040830184866131e1565b95945050505050565b6000602082840312156132a257600080fd5b8151612b3381612a9c565b6000602082840312156132bf57600080fd5b8135612b3381612e8b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561331c5761331c6132ca565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613369576133696132ca565b604052919050565b6000602080838503121561338457600080fd5b825167ffffffffffffffff8082111561339c57600080fd5b818501915085601f8301126133b057600080fd5b8151818111156133c2576133c26132ca565b6133d0848260051b01613322565b818152848101925060069190911b8301840190878211156133f057600080fd5b928401925b8184101561343c576040848903121561340e5760008081fd5b6134166132f9565b845161342181612a9c565b815284860151868201528352604090930192918401916133f5565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561348857613488613447565b500390565b8183823760009101908152919050565b6000602082840312156134af57600080fd5b815167ffffffffffffffff808211156134c757600080fd5b818401915084601f8301126134db57600080fd5b8151818111156134ed576134ed6132ca565b61351e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613322565b915080825285602082850101111561353557600080fd5b613546816020840160208601612f76565b50949350505050565b602081526000612b336020830184612fa2565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261317257600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261317257600080fd5b600181815b8085111561362357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561360957613609613447565b8085161561361657918102915b93841c93908002906135cf565b509250929050565b60008261363a575060016136e6565b81613647575060006136e6565b816001811461365d576002811461366757613683565b60019150506136e6565b60ff84111561367857613678613447565b50506001821b6136e6565b5060208310610133831016604e8410600b84101617156136a6575081810a6136e6565b6136b083836135ca565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156136e2576136e2613447565b0290505b92915050565b6000612b3360ff84168361362b565b60006020828403121561370d57600080fd5b813567ffffffffffffffff81168114612b3357600080fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561375d5761375d613447565b500290565b600082613798577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137d257600080fd5b83018035915067ffffffffffffffff8211156137ed57600080fd5b6020019150600781901b3603821315612bb757600080fd5b6000806040838503121561381857600080fd5b505080516020909101519092909150565b60008251613172818460208701612f76565b60006020828403121561384d57600080fd5b8151612b3381612e8b56fea26469706673582212200415ef60859319d7d187c25545410ef4faa3bb09dcd795c90e34fd5d95f1b99e64736f6c634300080a0033000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f50000000000000000000000004200000000000000000000000000000000000006

Deployed Bytecode

0x6080604052600436106101635760003560e01c8063783312d9116100c0578063ac9650d811610074578063c2e3140a11610059578063c2e3140a14610387578063cf58879a1461039a578063f3995c67146103ce57600080fd5b8063ac9650d814610354578063b96c5c0e1461037457600080fd5b806389a3f136116100a557806389a3f1361461031b5780639fa744911461032e578063a4a78f0c1461034157600080fd5b8063783312d9146102f55780637f6ad4551461030857600080fd5b80632c0d9a0111610117578063403335a8116100fc578063403335a81461029b5780634659a494146102ae5780634da31827146102c157600080fd5b80632c0d9a01146102755780632cfcb94f1461028857600080fd5b80630f93d439116101485780630f93d439146102175780631aa349a81461022a578063250558dc1461023d57600080fd5b8063018ee9b7146101de5780630b0d1b1e146101f157600080fd5b366101d9573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000420000000000000000000000000000000000000616146101d7576040517fe7218bb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b005b600080fd5b6101d76101ec366004612acc565b6103e1565b6102046101ff366004612af8565b610494565b6040519081526020015b60405180910390f35b610204610225366004612b3a565b610650565b6101d7610238366004612bbe565b610822565b61025061024b366004612c22565b61091a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161020e565b610204610283366004612af8565b6109de565b610204610296366004612c77565b610c1f565b6101d76102a9366004612d43565b610eae565b6101d76102bc366004612d76565b610f76565b3480156102cd57600080fd5b506102507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c481565b6101d7610303366004612dd0565b611031565b6101d7610316366004612e99565b61124b565b6101d7610329366004612ee4565b6114f8565b61020461033c366004612b3a565b611671565b6101d761034f366004612d76565b6116ad565b610367610362366004612f01565b611777565b60405161020e9190612fec565b6101d761038236600461306c565b6118e7565b6101d7610395366004612d76565b6124bc565b3480156103a657600080fd5b506102507f000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f581565b6101d76103dc366004612d76565b612562565b6040517f66c6bb0b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260016024830152604482018390527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c416906366c6bb0b90606401600060405180830381600087803b15801561047857600080fd5b505af115801561048c573d6000803e3d6000fd5b505050505050565b60006104ee6104a66020840184612ee4565b6104b360608501856130a7565b60008181106104c4576104c461310f565b90506020028101906104d6919061313e565b6104e4906020810190612ee4565b84602001356125df565b60006104fd60608401846130a7565b9050905060005b8181101561060b5761051960608501856130a7565b828181106105295761052961310f565b905060200281019061053b919061313e565b610549906020810190612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a61057160608701876130a7565b848181106105815761058161310f565b9050602002810190610593919061313e565b6105a190602081019061317c565b6040518363ffffffff1660e01b81526004016105be92919061322a565b6020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610601919061323e565b9250600101610504565b50826040013582101561064a576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f18d03cc61069e6080850160608601612ee4565b336106af6060870160408801612ee4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015284356064820152608401600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50610755925050506060830160408401612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a61077d608085018561317c565b6040518363ffffffff1660e01b815260040161079a92919061322a565b6020604051808303816000875af11580156107b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dd919061323e565b9050816020013581101561081d576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b61084473ffffffffffffffffffffffffffffffffffffffff86163387876126de565b6040517faf8c09bf00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff87169063af8c09bf9061089b908790879060040161322a565b6020604051808303816000875af11580156108ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108de919061323e565b90508181101561048c576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f250558dc00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f5169063250558dc9061099390879087908790600401613257565b6020604051808303816000875af11580156109b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d69190613290565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f18d03cc610a296020850185612ee4565b33610a3760608701876130a7565b6000818110610a4857610a4861310f565b9050602002810190610a5a919061313e565b610a68906020810190612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015260208501356064820152608401600060405180830381600087803b158015610ae857600080fd5b505af1158015610afc573d6000803e3d6000fd5b5060009250610b1191505060608401846130a7565b9050905060005b8181101561060b57610b2d60608501856130a7565b82818110610b3d57610b3d61310f565b9050602002810190610b4f919061313e565b610b5d906020810190612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a610b8560608701876130a7565b84818110610b9557610b9561310f565b9050602002810190610ba7919061313e565b610bb590602081019061317c565b6040518363ffffffff1660e01b8152600401610bd292919061322a565b6020604051808303816000875af1158015610bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c15919061323e565b9250600101610b18565b600085815b81811015610dcf57888882818110610c3e57610c3e61310f565b9050606002016020016020810190610c5691906132ad565b15610cad57610ca8898983818110610c7057610c7061310f565b610c869260206060909202019081019150612ee4565b888b8b85818110610c9957610c9961310f565b905060600201604001356125df565b610dc7565b7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663f18d03cc8a8a84818110610cfb57610cfb61310f565b610d119260206060909202019081019150612ee4565b338a8d8d87818110610d2557610d2561310f565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e08a901b16815273ffffffffffffffffffffffffffffffffffffffff978816600482015295871660248701529590931660448501525060609091020191909101356064820152608401600060405180830381600087803b158015610dae57600080fd5b505af1158015610dc2573d6000803e3d6000fd5b505050505b600101610c24565b506040517f7ba0e2e700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871690637ba0e2e790610e24908790879060040161322a565b6020604051808303816000875af1158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e67919061323e565b915084821015610ea3576040517f249942be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509695505050505050565b6040517fc0a47c930000000000000000000000000000000000000000000000000000000081523360048201523060248201526001604482015260ff841660648201526084810183905260a481018290527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff169063c0a47c939060c401600060405180830381600087803b158015610f5957600080fd5b505af1158015610f6d573d6000803e3d6000fd5b50505050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b600060405180830381600087803b15801561101157600080fd5b505af1158015611025573d6000803e3d6000fd5b50505050505050505050565b61105373ffffffffffffffffffffffffffffffffffffffff87163388886126de565b6040517f2a07b6c700000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff881690632a07b6c7906110aa908890889060040161322a565b6000604051808303816000875af11580156110c9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110f9190810190613371565b90508160005b818110156112405782818151811061112f5761112f61310f565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168585838181106111635761116361310f565b6111799260206040909202019081019150612ee4565b73ffffffffffffffffffffffffffffffffffffffff16146111c6576040517f2664ab9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484828181106111d8576111d861310f565b905060400201602001358382815181106111f4576111f461310f565b6020026020010151602001511015611238576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611115565b505050505050505050565b80156113cd576040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301523060248301526000917f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c49091169063f7888aec90604401602060405180830381865afa1580156112e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130c919061323e565b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301523060248301528581166044830152606482018390529192507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c49091169063f18d03cc90608401600060405180830381600087803b1580156113af57600080fd5b505af11580156113c3573d6000803e3d6000fd5b5050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff84161561148b576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260019073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015611458573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147c919061323e565b6114869190613476565b61148d565b475b905073ffffffffffffffffffffffffffffffffffffffff8416156114d1576114cc73ffffffffffffffffffffffffffffffffffffffff8516848361284f565b6114f1565b6114f173ffffffffffffffffffffffffffffffffffffffff8416826129b8565b505b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a9919061323e565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290529091507f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561163457600080fd5b505af1158015611648573d6000803e3d6000fd5b5061166d9250505073ffffffffffffffffffffffffffffffffffffffff8316826129b8565b5050565b600061169d6116866080840160608501612ee4565b6116966060850160408601612ee4565b84356125df565b6107556060830160408401612ee4565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611763919061323e565b101561048c5761048c868686868686610f76565b60608167ffffffffffffffff811115611792576117926132ca565b6040519080825280602002602001820160405280156117c557816020015b60608152602001906001900390816117b05790505b50905060005b828110156118e057600080308686858181106117e9576117e961310f565b90506020028101906117fb919061317c565b60405161180992919061348d565b600060405180830381855af49150503d8060008114611844576040519150601f19603f3d011682016040523d82523d6000602084013e611849565b606091505b5091509150816118b85760448151101561186257600080fd5b6004810190508080602001905181019061187c919061349d565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118af919061354f565b60405180910390fd5b808484815181106118cb576118cb61310f565b602090810291909101015250506001016117cb565b5092915050565b60006118f382806130a7565b9050905060005b81811015611c6c5761190c83806130a7565b8281811061191c5761191c61310f565b905060200281019061192e9190613562565b61193f9060608101906040016132ad565b156119f8576119f361195184806130a7565b838181106119615761196161310f565b90506020028101906119739190613562565b611981906020810190612ee4565b61198b85806130a7565b8481811061199b5761199b61310f565b90506020028101906119ad9190613562565b6119be906040810190602001612ee4565b6119c886806130a7565b858181106119d8576119d861310f565b90506020028101906119ea9190613562565b606001356125df565b611b71565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f18d03cc611a3e85806130a7565b84818110611a4e57611a4e61310f565b9050602002810190611a609190613562565b611a6e906020810190612ee4565b33611a7987806130a7565b86818110611a8957611a8961310f565b9050602002810190611a9b9190613562565b611aac906040810190602001612ee4565b611ab688806130a7565b87818110611ac657611ac661310f565b9050602002810190611ad89190613562565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff94851660048201529284166024840152921660448201526060909101356064820152608401600060405180830381600087803b158015611b5857600080fd5b505af1158015611b6c573d6000803e3d6000fd5b505050505b611b7b83806130a7565b82818110611b8b57611b8b61310f565b9050602002810190611b9d9190613562565b611bae906040810190602001612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a611bd385806130a7565b84818110611be357611be361310f565b9050602002810190611bf59190613562565b611c0390608081019061317c565b6040518363ffffffff1660e01b8152600401611c2092919061322a565b6020604051808303816000875af1158015611c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c63919061323e565b506001016118fa565b50611c7a60208301836130a7565b9050905060005b8181101561206357600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f7888aec611cd460208701876130a7565b85818110611ce457611ce461310f565b9050602002810190611cf69190613596565b611d04906020810190612ee4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015611d73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d97919061323e565b90506000611da76008600a6136ec565b611db460208701876130a7565b85818110611dc457611dc461310f565b9050602002810190611dd69190613596565b611de79060608101906040016136fb565b611dfb9067ffffffffffffffff1684613725565b611e059190613762565b905073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f18d03cc611e5060208801886130a7565b86818110611e6057611e6061310f565b9050602002810190611e729190613596565b611e80906020810190612ee4565b30611e8e60208a018a6130a7565b88818110611e9e57611e9e61310f565b9050602002810190611eb09190613596565b611ec1906040810190602001612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015260648101849052608401600060405180830381600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b50611f649250505060208601866130a7565b84818110611f7457611f7461310f565b9050602002810190611f869190613596565b611f97906040810190602001612ee4565b73ffffffffffffffffffffffffffffffffffffffff1663627dd56a611fbf60208801886130a7565b86818110611fcf57611fcf61310f565b9050602002810190611fe19190613596565b611fef90606081019061317c565b6040518363ffffffff1660e01b815260040161200c92919061322a565b6020604051808303816000875af115801561202b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204f919061323e565b50505061205c8160010190565b9050611c81565b50612071604083018361379d565b9050905060005b818110156114f357600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f7888aec6120cb604087018761379d565b858181106120db576120db61310f565b6120f19260206080909202019081019150612ee4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015612160573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612184919061323e565b9050612193604085018561379d565b838181106121a3576121a361310f565b905060800201606001358110156121e6576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121f3604085018561379d565b838181106122035761220361310f565b905060800201604001602081019061221b91906132ad565b156123785773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4166397da6d30612269604087018761379d565b858181106122795761227961310f565b61228f9260206080909202019081019150612ee4565b3061229d604089018961379d565b878181106122ad576122ad61310f565b90506080020160200160208101906122c59190612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529091166044820152600060648201526084810184905260a40160408051808303816000875af115801561234d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123719190613805565b50506124b3565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41663f18d03cc6123c1604087018761379d565b858181106123d1576123d161310f565b6123e79260206080909202019081019150612ee4565b306123f5604089018961379d565b878181106124055761240561310f565b905060800201602001602081019061241d9190612ee4565b60405160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152909116604482015260648101849052608401600060405180830381600087803b15801561249a57600080fd5b505af11580156124ae573d6000803e3d6000fd5b505050505b50600101612078565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa15801561252e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612552919061323e565b101561048c5761048c8686868686865b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e401610ff7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c48116906302b9446c9085161561262c57600061262e565b825b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff808816600483015233602483015286166044820152606481018590526000608482015260a401604080518083038185885af11580156126b2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906126d79190613805565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161277d9190613829565b6000604051808303816000865af19150503d80600081146127ba576040519150601f19603f3d011682016040523d82523d6000602084013e6127bf565b606091505b50915091508180156127e95750805115806127e95750808060200190518101906127e9919061383b565b61048c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f535446000000000000000000000000000000000000000000000000000000000060448201526064016118af565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916128e69190613829565b6000604051808303816000865af19150503d8060008114612923576040519150601f19603f3d011682016040523d82523d6000602084013e612928565b606091505b5091509150818015612952575080511580612952575080806020019051810190612952919061383b565b6126d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064016118af565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516129ef9190613829565b60006040518083038185875af1925050503d8060008114612a2c576040519150601f19603f3d011682016040523d82523d6000602084013e612a31565b606091505b50509050806114f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f535445000000000000000000000000000000000000000000000000000000000060448201526064016118af565b73ffffffffffffffffffffffffffffffffffffffff81168114612abe57600080fd5b50565b803561081d81612a9c565b60008060408385031215612adf57600080fd5b8235612aea81612a9c565b946020939093013593505050565b600060208284031215612b0a57600080fd5b813567ffffffffffffffff811115612b2157600080fd5b820160808185031215612b3357600080fd5b9392505050565b600060208284031215612b4c57600080fd5b813567ffffffffffffffff811115612b6357600080fd5b820160a08185031215612b3357600080fd5b60008083601f840112612b8757600080fd5b50813567ffffffffffffffff811115612b9f57600080fd5b602083019150836020828501011115612bb757600080fd5b9250929050565b600080600080600060808688031215612bd657600080fd5b8535612be181612a9c565b945060208601359350604086013567ffffffffffffffff811115612c0457600080fd5b612c1088828901612b75565b96999598509660600135949350505050565b600080600060408486031215612c3757600080fd5b8335612c4281612a9c565b9250602084013567ffffffffffffffff811115612c5e57600080fd5b612c6a86828701612b75565b9497909650939450505050565b60008060008060008060808789031215612c9057600080fd5b863567ffffffffffffffff80821115612ca857600080fd5b818901915089601f830112612cbc57600080fd5b813581811115612ccb57600080fd5b8a6020606083028501011115612ce057600080fd5b60208301985080975050612cf660208a01612ac1565b9550604089013594506060890135915080821115612d1357600080fd5b50612d2089828a01612b75565b979a9699509497509295939492505050565b803560ff8116811461081d57600080fd5b600080600060608486031215612d5857600080fd5b612d6184612d32565b95602085013595506040909401359392505050565b60008060008060008060c08789031215612d8f57600080fd5b8635612d9a81612a9c565b95506020870135945060408701359350612db660608801612d32565b92506080870135915060a087013590509295509295509295565b60008060008060008060808789031215612de957600080fd5b8635612df481612a9c565b955060208701359450604087013567ffffffffffffffff80821115612e1857600080fd5b612e248a838b01612b75565b90965094506060890135915080821115612e3d57600080fd5b818901915089601f830112612e5157600080fd5b813581811115612e6057600080fd5b8a60208260061b8501011115612e7557600080fd5b6020830194508093505050509295509295509295565b8015158114612abe57600080fd5b600080600060608486031215612eae57600080fd5b8335612eb981612a9c565b92506020840135612ec981612a9c565b91506040840135612ed981612e8b565b809150509250925092565b600060208284031215612ef657600080fd5b8135612b3381612a9c565b60008060208385031215612f1457600080fd5b823567ffffffffffffffff80821115612f2c57600080fd5b818501915085601f830112612f4057600080fd5b813581811115612f4f57600080fd5b8660208260051b8501011115612f6457600080fd5b60209290920196919550909350505050565b60005b83811015612f91578181015183820152602001612f79565b838111156114f15750506000910152565b60008151808452612fba816020860160208601612f76565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561305f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261304d858351612fa2565b94509285019290850190600101613013565b5092979650505050505050565b60006020828403121561307e57600080fd5b813567ffffffffffffffff81111561309557600080fd5b820160608185031215612b3357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126130dc57600080fd5b83018035915067ffffffffffffffff8211156130f757600080fd5b6020019150600581901b3603821315612bb757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261317257600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126131b157600080fd5b83018035915067ffffffffffffffff8211156131cc57600080fd5b602001915036819003821315612bb757600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006109d66020830184866131e1565b60006020828403121561325057600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006132876040830184866131e1565b95945050505050565b6000602082840312156132a257600080fd5b8151612b3381612a9c565b6000602082840312156132bf57600080fd5b8135612b3381612e8b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561331c5761331c6132ca565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613369576133696132ca565b604052919050565b6000602080838503121561338457600080fd5b825167ffffffffffffffff8082111561339c57600080fd5b818501915085601f8301126133b057600080fd5b8151818111156133c2576133c26132ca565b6133d0848260051b01613322565b818152848101925060069190911b8301840190878211156133f057600080fd5b928401925b8184101561343c576040848903121561340e5760008081fd5b6134166132f9565b845161342181612a9c565b815284860151868201528352604090930192918401916133f5565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561348857613488613447565b500390565b8183823760009101908152919050565b6000602082840312156134af57600080fd5b815167ffffffffffffffff808211156134c757600080fd5b818401915084601f8301126134db57600080fd5b8151818111156134ed576134ed6132ca565b61351e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613322565b915080825285602082850101111561353557600080fd5b613546816020840160208601612f76565b50949350505050565b602081526000612b336020830184612fa2565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261317257600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261317257600080fd5b600181815b8085111561362357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561360957613609613447565b8085161561361657918102915b93841c93908002906135cf565b509250929050565b60008261363a575060016136e6565b81613647575060006136e6565b816001811461365d576002811461366757613683565b60019150506136e6565b60ff84111561367857613678613447565b50506001821b6136e6565b5060208310610133831016604e8410600b84101617156136a6575081810a6136e6565b6136b083836135ca565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156136e2576136e2613447565b0290505b92915050565b6000612b3360ff84168361362b565b60006020828403121561370d57600080fd5b813567ffffffffffffffff81168114612b3357600080fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561375d5761375d613447565b500290565b600082613798577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137d257600080fd5b83018035915067ffffffffffffffff8211156137ed57600080fd5b6020019150600781901b3603821315612bb757600080fd5b6000806040838503121561381857600080fd5b505080516020909101519092909150565b60008251613172818460208701612f76565b60006020828403121561384d57600080fd5b8151612b3381612e8b56fea26469706673582212200415ef60859319d7d187c25545410ef4faa3bb09dcd795c90e34fd5d95f1b99e64736f6c634300080a0033

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

000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f50000000000000000000000004200000000000000000000000000000000000006

-----Decoded View---------------
Arg [0] : _bento (address): 0xc35DADB65012eC5796536bD9864eD8773aBc74C4
Arg [1] : _masterDeployer (address): 0xCaAbdD9Cf4b61813D4a52f980d6BC1B713FE66F5
Arg [2] : _wETH (address): 0x4200000000000000000000000000000000000006

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4
Arg [1] : 000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f5
Arg [2] : 0000000000000000000000004200000000000000000000000000000000000006


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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.