Contract 0x8f54301f315c56c112d492d9443047d4745dbe9e 12

 
Txn Hash Method
Block
From
To
Value
0xc8d6b5435579851c5804a43e49e2390211e3f1be99e94206ccf7bd4b741996c0Cook144006012022-07-13 14:15:41624 days 2 hrs ago0x8f66b72728314c6b1aef199876014eb6014fe6e2 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0.000517441558961 ETH0.0004700128160.001
0x8517963764734c219de23bc9aeab39a406ae858f0e5a46f03d148bebb2d13d07Cook132954612022-06-27 13:40:14640 days 3 hrs ago0x17b2c6dc3d2f5faead8135addae008755092a9ee IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0.00001 ETH0.0005935113150.001
0xdd080c31af600f5a58e8b1e63946b1a88f3c535e74f43943636e3732d66a7bfcCook130939062022-06-26 3:06:05641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.00028021260.001
0x88cf87dc6ed5ac25f99216f75c2bb21c855a4d2a300004e7e03626044bbe519aCook130932992022-06-26 2:59:22641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0002821379060.001
0x504c681a3244d69bc0d6f3e6400c13b28fcfec34b4af7b996647aad04b8b1aceCook130932282022-06-26 2:58:37641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.000282144620.001
0x3458f80095f3f65005966a411db06afde83b83760017404a073b3428525a2e69Cook130931482022-06-26 2:57:37641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.000316460.001
0x8c43cc079c34f4129921d4d7ba725797c5f3bdb8b5982edad65e7313f9152e4dCook130924852022-06-26 2:51:00641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0001538951910.001
0xa4dd2234c58802400811237479ef53f131757846b887084be94f9de85f57787bCook130924032022-06-26 2:50:14641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0001731668160.001
0x7b5fb8754cda0bdfe8ede29fd8c2d0c288765282e7a6a1b6f4afb40b89bd3201Cook130923162022-06-26 2:49:29641 days 14 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0001555728830.001
0x878fb44f8de71f6fbc65e62159150798e5c2a1fc5e61a13f4851469dc5b447ccCook129126552022-06-24 11:05:10643 days 6 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0003616195610.001
0x070594895921c9ab4f4ffd7260c8d1dca029de930f475962dd979e1faa588c47Cook129117802022-06-24 10:55:23643 days 6 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0.01 ETH0.0001712304550.001
0xcab46d33e78685d91de350984848e49eb0a13bc7e9b3bd9201e315b5566888b6Cook129114002022-06-24 10:51:46643 days 6 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0.01 ETH0.00026611280.001
0x140d23732307ec1bdddff32dbc3d3c09f55b70365502f59753fb4c6620bffdc5Cook129110032022-06-24 10:47:41643 days 6 hrs ago0x8f54c8c2df62c94772ac14ccfc85603742976312 IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0003520584350.001
0x37fe32c812383ee28faa3bc85845893e5dbb5f9cec41742836bdc798f094bb79Approve To Starg...129092022022-06-24 10:23:36643 days 6 hrs ago0xf87bc5535602077d340806d71f805ea9907a843d IN  0x8f54301f315c56c112d492d9443047d4745dbe9e0 ETH0.0001017221230.001
0xf31a61ceed242482b74929689e1dbbbb4ac20829597b10098b67a06ae366a7640x61010060129091992022-06-24 10:23:36643 days 6 hrs ago0xf87bc5535602077d340806d71f805ea9907a843d IN  Create: SushiXSwap0 ETH0.0069068282470.001
[ Download CSV Export 
Latest 22 internal transactions
Parent Txn Hash Block From To Value
0xc8d6b5435579851c5804a43e49e2390211e3f1be99e94206ccf7bd4b741996c0144006012022-07-13 14:15:41624 days 2 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9eStargate Finance: Router0.000517441558961238 ETH
0xbe01cb5d8b8936fef8b06ecfaf10a1b7948a6508dc87354a1752c023acdf658b138447842022-07-04 21:08:08632 days 20 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x60ca4a332243ec11354ca740bc2888a81f9e07f20.015984574269379428 ETH
0xbe01cb5d8b8936fef8b06ecfaf10a1b7948a6508dc87354a1752c023acdf658b138447842022-07-04 21:08:08632 days 20 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.015984574269379428 ETH
0x8517963764734c219de23bc9aeab39a406ae858f0e5a46f03d148bebb2d13d07132954612022-06-27 13:40:14640 days 3 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9eSushiSwap: BentoBoxV10.00001 ETH
0xdd080c31af600f5a58e8b1e63946b1a88f3c535e74f43943636e3732d66a7bfc130939062022-06-26 3:06:05641 days 14 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.008276687866563087 ETH
0xdd080c31af600f5a58e8b1e63946b1a88f3c535e74f43943636e3732d66a7bfc130939062022-06-26 3:06:05641 days 14 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.008276687866563087 ETH
0x8c43cc079c34f4129921d4d7ba725797c5f3bdb8b5982edad65e7313f9152e4d130924852022-06-26 2:51:00641 days 14 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.004151676068235629 ETH
0x8c43cc079c34f4129921d4d7ba725797c5f3bdb8b5982edad65e7313f9152e4d130924852022-06-26 2:51:00641 days 14 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.004151676068235629 ETH
0xa4dd2234c58802400811237479ef53f131757846b887084be94f9de85f57787b130924032022-06-26 2:50:14641 days 14 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.000831278236807027 ETH
0xa4dd2234c58802400811237479ef53f131757846b887084be94f9de85f57787b130924032022-06-26 2:50:14641 days 14 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.000831278236807027 ETH
0x3a025d2cbab7b918f08260f16fd4607b3add43f5efab6512e222f3ec1346b529129192622022-06-24 12:07:28643 days 5 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.016637578187841849 ETH
0x3a025d2cbab7b918f08260f16fd4607b3add43f5efab6512e222f3ec1346b529129192622022-06-24 12:07:28643 days 5 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.016637578187841849 ETH
0x878fb44f8de71f6fbc65e62159150798e5c2a1fc5e61a13f4851469dc5b447cc129126552022-06-24 11:05:10643 days 6 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.000086435280989795 ETH
0x878fb44f8de71f6fbc65e62159150798e5c2a1fc5e61a13f4851469dc5b447cc129126552022-06-24 11:05:10643 days 6 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.000086435280989795 ETH
0x146a291b7cdf8f075fe3464189c03e090be377768747e0eb2b296bb3aeed7e82129120822022-06-24 10:58:28643 days 6 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.015754364308912305 ETH
0x146a291b7cdf8f075fe3464189c03e090be377768747e0eb2b296bb3aeed7e82129120822022-06-24 10:58:28643 days 6 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.015754364308912305 ETH
0x070594895921c9ab4f4ffd7260c8d1dca029de930f475962dd979e1faa588c47129117802022-06-24 10:55:23643 days 6 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9eSushiSwap: BentoBoxV10.01 ETH
0xcab46d33e78685d91de350984848e49eb0a13bc7e9b3bd9201e315b5566888b6129114002022-06-24 10:51:46643 days 6 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9eSushiSwap: BentoBoxV10.01 ETH
0x140d23732307ec1bdddff32dbc3d3c09f55b70365502f59753fb4c6620bffdc5129110032022-06-24 10:47:41643 days 6 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.004095183104240834 ETH
0x140d23732307ec1bdddff32dbc3d3c09f55b70365502f59753fb4c6620bffdc5129110032022-06-24 10:47:41643 days 6 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.004095183104240834 ETH
0xa2f6b3f3efeb64974fa926e2c45b73472ba4228ed7283fe42317d69c8ef22e9f129095342022-06-24 10:28:36643 days 6 hrs ago 0x8f54301f315c56c112d492d9443047d4745dbe9e0x8f54c8c2df62c94772ac14ccfc856037429763120.015491390078067336 ETH
0xa2f6b3f3efeb64974fa926e2c45b73472ba4228ed7283fe42317d69c8ef22e9f129095342022-06-24 10:28:36643 days 6 hrs ago Wrapped Ether 0x8f54301f315c56c112d492d9443047d4745dbe9e0.015491390078067336 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SushiXSwap

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 999999 runs

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

pragma solidity 0.8.11;

import "./interfaces/ISushiXSwap.sol";

/// @title SushiXSwap
/// @notice Enables cross chain swap for sushiswap.
/// @dev Supports both BentoBox and Wallet. Supports both Trident and Legacy AMM. Uses Stargate as bridge.
contract SushiXSwap is
    ISushiXSwap,
    BentoAdapter,
    TokenAdapter,
    SushiLegacyAdapter,
    TridentSwapAdapter,
    StargateAdapter
{
    constructor(
        IBentoBoxMinimal _bentoBox,
        IStargateRouter _stargateRouter,
        address _factory,
        bytes32 _pairCodeHash
    ) ImmutableState(_bentoBox, _stargateRouter, _factory, _pairCodeHash) {
        // Register to BentoBox
        _bentoBox.registerProtocol();
    }

    /// @notice List of ACTIONS supported by the `cook()`.

    // Bento and Token Operations
    uint8 internal constant ACTION_MASTER_CONTRACT_APPROVAL = 0;
    uint8 internal constant ACTION_SRC_DEPOSIT_TO_BENTOBOX = 1;
    uint8 internal constant ACTION_SRC_TRANSFER_FROM_BENTOBOX = 2;
    uint8 internal constant ACTION_DST_DEPOSIT_TO_BENTOBOX = 3;
    uint8 internal constant ACTION_DST_WITHDRAW_TOKEN = 4;
    uint8 internal constant ACTION_DST_WITHDRAW_OR_TRANSFER_FROM_BENTOBOX = 5;
    uint8 internal constant ACTION_UNWRAP_AND_TRANSFER = 6;

    // Swap Operations
    uint8 internal constant ACTION_LEGACY_SWAP = 7;
    uint8 internal constant ACTION_TRIDENT_SWAP = 8;
    uint8 internal constant ACTION_TRIDENT_COMPLEX_PATH_SWAP = 9;

    // Bridge Operations
    uint8 internal constant ACTION_STARGATE_TELEPORT = 10;

    uint8 internal constant ACTION_SRC_TOKEN_TRANSFER = 11;

    /// @notice Executes a set of actions and allows composability (contract calls) to other contracts.
    /// @param actions An array with a sequence of actions to execute (see ACTION_ declarations).
    /// @param values A one-to-one mapped array to `actions`. Native token amount to send along action.
    /// @param datas A one-to-one mapped array to `actions`. Contains abi encoded data of function arguments.
    /// @dev The function gets invoked both at the src and dst chain.
    function cook(
        uint8[] memory actions,
        uint256[] memory values,
        bytes[] memory datas
    ) public payable override {
        uint256 actionLength = actions.length;
        for (uint256 i; i < actionLength; i = _increment(i)) {
            uint8 action = actions[i];
            // update for total amounts in contract?
            if (action == ACTION_MASTER_CONTRACT_APPROVAL) {
                (
                    address user,
                    bool approved,
                    uint8 v,
                    bytes32 r,
                    bytes32 s
                ) = abi.decode(
                        datas[i],
                        (address, bool, uint8, bytes32, bytes32)
                    );

                bentoBox.setMasterContractApproval(
                    user,
                    address(this),
                    approved,
                    v,
                    r,
                    s
                );
            } else if (action == ACTION_SRC_DEPOSIT_TO_BENTOBOX) {
                (address token, address to, uint256 amount, uint256 share) = abi
                    .decode(datas[i], (address, address, uint256, uint256));
                _depositToBentoBox(
                    token,
                    msg.sender,
                    to,
                    amount,
                    share,
                    values[i]
                );
            } else if (action == ACTION_SRC_TRANSFER_FROM_BENTOBOX) {
                (
                    address token,
                    address to,
                    uint256 amount,
                    uint256 share,
                    bool unwrapBento
                ) = abi.decode(
                        datas[i],
                        (address, address, uint256, uint256, bool)
                    );
                _transferFromBentoBox(
                    token,
                    msg.sender,
                    to,
                    amount,
                    share,
                    unwrapBento
                );
            } else if (action == ACTION_SRC_TOKEN_TRANSFER) {
                (address token, address to, uint256 amount) = abi.decode(
                    datas[i],
                    (address, address, uint256)
                );

                _transferFromToken(IERC20(token), to, amount);
            } else if (action == ACTION_DST_DEPOSIT_TO_BENTOBOX) {
                (address token, address to, uint256 amount, uint256 share) = abi
                    .decode(datas[i], (address, address, uint256, uint256));

                if (amount == 0) {
                    amount = IERC20(token).balanceOf(address(this));
                    // Stargate Router doesn't support value? Should we update it anyway?
                    // values[i] = address(this).balance;
                }

                _transferTokens(IERC20(token), address(bentoBox), amount);

                _depositToBentoBox(
                    token,
                    address(bentoBox),
                    to,
                    amount,
                    share,
                    values[i]
                );
            } else if (action == ACTION_DST_WITHDRAW_TOKEN) {
                (address token, address to, uint256 amount) = abi.decode(
                    datas[i],
                    (address, address, uint256)
                );
                if (amount == 0) {
                    if (token != address(0)) {
                        amount = IERC20(token).balanceOf(address(this));
                    } else {
                        amount = address(this).balance;
                    }
                }
                _transferTokens(IERC20(token), to, amount);
            } else if (
                action == ACTION_DST_WITHDRAW_OR_TRANSFER_FROM_BENTOBOX
            ) {
                (
                    address token,
                    address to,
                    uint256 amount,
                    uint256 share,
                    bool unwrapBento
                ) = abi.decode(
                        datas[i],
                        (address, address, uint256, uint256, bool)
                    );
                if (amount == 0 && share == 0) {
                    share = bentoBox.balanceOf(token, address(this));
                }
                _transferFromBentoBox(
                    token,
                    address(this),
                    to,
                    amount,
                    share,
                    unwrapBento
                );
            } else if (action == ACTION_UNWRAP_AND_TRANSFER) {
                (address token, address to) = abi.decode(
                    datas[i],
                    (address, address)
                );

                _unwrapTransfer(token, to);
            } else if (action == ACTION_LEGACY_SWAP) {
                (
                    uint256 amountIn,
                    uint256 amountOutMin,
                    address[] memory path,
                    address to
                ) = abi.decode(
                        datas[i],
                        (uint256, uint256, address[], address)
                    );
                bool sendTokens;
                if (amountIn == 0) {
                    amountIn = IERC20(path[0]).balanceOf(address(this));
                    sendTokens = true;
                }
                _swapExactTokensForTokens(
                    amountIn,
                    amountOutMin,
                    path,
                    to,
                    sendTokens
                );
            } else if (action == ACTION_TRIDENT_SWAP) {
                ExactInputParams memory params = abi.decode(
                    datas[i],
                    (ExactInputParams)
                );

                _exactInput(params);
            } else if (action == ACTION_TRIDENT_COMPLEX_PATH_SWAP) {
                ComplexPathParams memory params = abi.decode(
                    datas[i],
                    (ComplexPathParams)
                );

                _complexPath(params);
            } else if (action == ACTION_STARGATE_TELEPORT) {
                (
                    StargateTeleportParams memory params,
                    uint8[] memory actionsDST,
                    uint256[] memory valuesDST,
                    bytes[] memory datasDST
                ) = abi.decode(
                        datas[i],
                        (StargateTeleportParams, uint8[], uint256[], bytes[])
                    );

                _stargateTeleport(params, actionsDST, valuesDST, datasDST);
            }
        }
    }

    /// @notice Allows the contract to receive Native tokens
    receive() external payable {}
}

File 2 of 24 : ISushiXSwap.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "../adapters/BentoAdapter.sol";
import "../adapters/TokenAdapter.sol";
import "../adapters/SushiLegacyAdapter.sol";
import "../adapters/TridentSwapAdapter.sol";
import "../adapters/StargateAdapter.sol";

interface ISushiXSwap {
    function cook(
        uint8[] memory actions,
        uint256[] memory values,
        bytes[] memory datas
    ) external payable;
}

File 3 of 24 : BentoAdapter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "../interfaces/IBentoBoxMinimal.sol";
import "../base/ImmutableState.sol";

/// @title BentoAdapter
/// @notice Adapter which provides all functions of BentoBox require by this contract.
/// @dev These are generic functions, make sure, only msg.sender, address(this) and address(bentoBox)
/// are passed in the from param, or else the attacker can sifu user's funds in bentobox.
abstract contract BentoAdapter is ImmutableState {
    /// @notice Deposits the token from users wallet into the BentoBox.
    /// @dev Make sure, only msg.sender, address(this) and address(bentoBox)
    /// are passed in the from param, or else the attacker can sifu user's funds in bentobox.
    /// Pass either amount or share.
    /// @param token token to deposit. Use token as address(0) when depositing native token
    /// @param from sender
    /// @param to receiver
    /// @param amount amount to be deposited
    /// @param share share to be deposited
    /// @param value native token value to be deposited. Only use when token address is address(0)
    function _depositToBentoBox(
        address token,
        address from,
        address to,
        uint256 amount,
        uint256 share,
        uint256 value
    ) internal {
        bentoBox.deposit{value: value}(token, from, to, amount, share);
    }

    /// @notice Transfers the token from bentobox user to another or withdraw it to another address.
    /// @dev Make sure, only msg.sender, address(this) and address(bentoBox)
    /// are passed in the from param, or else the attacker can sifu user's funds in bentobox.
    /// Pass either amount or share.
    /// @param token token to transfer. For native tokens, use wnative token address
    /// @param from sender
    /// @param to receiver
    /// @param amount amount to transfer
    /// @param share share to transfer
    /// @param unwrapBento use true for withdraw and false for transfer
    function _transferFromBentoBox(
        address token,
        address from,
        address to,
        uint256 amount,
        uint256 share,
        bool unwrapBento
    ) internal {
        if (unwrapBento) {
            bentoBox.withdraw(token, from, to, amount, share);
        } else {
            if (amount > 0) {
                share = bentoBox.toShare(token, amount, false);
            }
            bentoBox.transfer(token, from, to, share);
        }
    }
}

File 4 of 24 : TokenAdapter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IWETH.sol";

/// @title TokenAdapter
/// @notice Adapter for all token operations
abstract contract TokenAdapter {
    using SafeERC20 for IERC20;

    /// @notice Function to transfer tokens from address(this)
    /// @param token token to transfer
    /// @param to receiver
    /// @param amount amount to transfer
    function _transferTokens(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        if (address(token) != address(0)) {
            token.safeTransfer(to, amount);
        } else {
            payable(to).transfer(amount);
        }
    }

    /// @notice Function to transfer tokens from user to the to address
    /// @param token token to transfer
    /// @param to receiver
    /// @param amount amount to transfer
    function _transferFromToken(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        token.safeTransferFrom(msg.sender, to, amount);
    }

    /// @notice Unwraps the wrapper native into native and sends it to the receiver.
    /// @param token token to transfer
    /// @param to receiver
    function _unwrapTransfer(address token, address to) internal {
        IWETH(token).withdraw(IERC20(token).balanceOf(address(this)));
        _transferTokens(IERC20(address(0)), to, address(this).balance);
    }
}

File 5 of 24 : SushiLegacyAdapter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../libraries/UniswapV2Library.sol";
import "../base/ImmutableState.sol";

/// @title SushiLegacyAdapter
/// @notice Adapter for functions used to swap using Sushiswap Legacy AMM.
abstract contract SushiLegacyAdapter is ImmutableState {
    using SafeERC20 for IERC20;

    function _swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path,
        address to,
        bool sendTokens
    ) internal returns (uint256 amountOut) {
        uint256[] memory amounts = UniswapV2Library.getAmountsOut(
            factory,
            amountIn,
            path,
            pairCodeHash
        );
        amountOut = amounts[amounts.length - 1];

        require(amountOut >= amountOutMin, "insufficient-amount-out");

        /// @dev force sends token to the first pair if not already sent
        if (sendTokens) {
            IERC20(path[0]).safeTransfer(
                UniswapV2Library.pairFor(
                    factory,
                    path[0],
                    path[1],
                    pairCodeHash
                ),
                IERC20(path[0]).balanceOf(address(this))
            );
        }
        _swap(amounts, path, to);
    }

    /// @dev requires the initial amount to have already been sent to the first pair
    function _swap(
        uint256[] memory amounts,
        address[] memory path,
        address _to
    ) internal virtual {
        for (uint256 i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0, ) = UniswapV2Library.sortTokens(input, output);
            uint256 amountOut = amounts[i + 1];
            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint256(0), amountOut)
                : (amountOut, uint256(0));
            address to = i < path.length - 2
                ? UniswapV2Library.pairFor(
                    factory,
                    output,
                    path[i + 2],
                    pairCodeHash
                )
                : _to;
            IUniswapV2Pair(
                UniswapV2Library.pairFor(factory, input, output, pairCodeHash)
            ).swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }
}

File 6 of 24 : TridentSwapAdapter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "../interfaces/trident/ITridentSwapAdapter.sol";

/// @title TridentSwapAdapter
/// @notice Adapter for all Trident based Swaps

abstract contract TridentSwapAdapter is
    ITridentRouter,
    ImmutableState,
    BentoAdapter,
    TokenAdapter
{
    // Custom Error
    error TooLittleReceived();

    /// @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 _exactInput(ExactInputParams memory params)
        internal
        returns (uint256 amountOut)
    {
        if (params.amountIn == 0) {
          uint256 tokenBalance = IERC20(params.tokenIn).balanceOf(
                address(this)
            );
            _transferTokens(
                IERC20(params.tokenIn),
                address(bentoBox),
                tokenBalance
            );
            // Pay the first pool directly.
            (, params.amountIn) = bentoBox.deposit(
                params.tokenIn,
                address(bentoBox),
                params.path[0].pool,
                tokenBalance,
                0
            );
        }

        // 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 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 memory params) internal {
        // 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)) {
            bentoBox.transfer(
                params.initialPath[i].tokenIn,
                address(this),
                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 = bentoBox.balanceOf(
                params.percentagePath[i].tokenIn,
                address(this)
            );
            uint256 transferShares = (balanceShares *
                params.percentagePath[i].balancePercentage) / uint256(10)**8;
            bentoBox.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 = bentoBox.balanceOf(
                params.output[i].token,
                address(this)
            );
            if (balanceShares < params.output[i].minAmount)
                revert TooLittleReceived();
            if (params.output[i].unwrapBento) {
                bentoBox.withdraw(
                    params.output[i].token,
                    address(this),
                    params.output[i].to,
                    0,
                    balanceShares
                );
            } else {
                bentoBox.transfer(
                    params.output[i].token,
                    address(this),
                    params.output[i].to,
                    balanceShares
                );
            }
        }
    }

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

File 7 of 24 : StargateAdapter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "../interfaces/stargate/IStargateAdapter.sol";

/// @title StargateAdapter
/// @notice Adapter for function used by Stargate Bridge
abstract contract StargateAdapter is ImmutableState, IStargateReceiver {
    using SafeERC20 for IERC20;

    // Custom Error
    error NotStargateRouter();

    struct StargateTeleportParams {
        uint16 dstChainId; // stargate dst chain id
        address token; // token getting bridged
        uint256 srcPoolId; // stargate src pool id
        uint256 dstPoolId; // stargate dst pool id
        uint256 amount; // amount to bridge
        uint256 amountMin; // amount to bridge minimum
        uint256 dustAmount; // native token to be received on dst chain
        address receiver; // sushiXswap on dst chain
        address to; // receiver bridge token incase of transaction reverts on dst chain
        uint256 gas; // extra gas to be sent for dst chain operations
    }

    /// @notice Approves token to the Stargate Router
    /// @param token token to approve
    function approveToStargateRouter(IERC20 token) external {
        token.safeApprove(address(stargateRouter), type(uint256).max);
    }

    /// @notice Bridges the token to dst chain using Stargate Router
    /// @dev It is hardcoded to use all the contract balance. Only call this as the last step.
    /// The refund address for extra fees sent it msg.sender.
    /// @param params required by the Stargate, can be found at StargateTeleportParams struct.
    /// @param actions An array with a sequence of actions to execute (see ACTION_ declarations).
    /// @param values A one-to-one mapped array to `actions`. Native token amount to send along action.
    /// @param datas A one-to-one mapped array to `actions`. Contains abi encoded data of function arguments.
    function _stargateTeleport(
        StargateTeleportParams memory params,
        uint8[] memory actions,
        uint256[] memory values,
        bytes[] memory datas
    ) internal {
        bytes memory payload = abi.encode(params.to, actions, values, datas);

        stargateRouter.swap{value: address(this).balance}(
            params.dstChainId,
            params.srcPoolId,
            params.dstPoolId,
            payable(msg.sender), // refund address
            params.amount != 0
                ? params.amount
                : IERC20(params.token).balanceOf(address(this)),
            params.amountMin,
            IStargateRouter.lzTxObj(
                params.gas, // extra gas to be sent for dst execution
                params.dustAmount,
                abi.encodePacked(params.receiver)
            ),
            abi.encodePacked(params.receiver), // sushiXswap on the dst chain
            payload
        );
    }

    /// @notice Get the fees to be paid in native token for the swap
    /// @param _dstChainId stargate dst chainId
    /// @param _functionType stargate Function type 1 for swap.
    /// See more at https://stargateprotocol.gitbook.io/stargate/developers/function-types
    /// @param _receiver sushiXswap on the dst chain
    /// @param _gas extra gas being sent
    /// @param _dustAmount dust amount to be received at the dst chain
    /// @param _payload payload being sent at the dst chain
    function getFee(
        uint16 _dstChainId,
        uint8 _functionType,
        address _receiver,
        uint256 _gas,
        uint256 _dustAmount,
        bytes memory _payload
    ) external view returns (uint256 a, uint256 b) {
        (a, b) = stargateRouter.quoteLayerZeroFee(
            _dstChainId,
            _functionType,
            abi.encodePacked(_receiver),
            abi.encode(_payload),
            IStargateRouter.lzTxObj(
                _gas,
                _dustAmount,
                abi.encodePacked(_receiver)
            )
        );
    }

    /// @notice Receiver function on dst chain
    /// @param _token bridge token received
    /// @param amountLD amount received
    /// @param payload ABI-Encoded data received from src chain
    function sgReceive(
        uint16,
        bytes memory,
        uint256,
        address _token,
        uint256 amountLD,
        bytes memory payload
    ) external override {
        if (msg.sender != address(stargateRouter)) revert NotStargateRouter();

        (
            address to,
            uint8[] memory actions,
            uint256[] memory values,
            bytes[] memory datas
        ) = abi.decode(payload, (address, uint8[], uint256[], bytes[]));

        /// @dev incase the actions fail, transfer bridge token to the to address
        try
            ISushiXSwap(payable(address(this))).cook(actions, values, datas)
        {} catch (bytes memory) {
            IERC20(_token).transfer(to, amountLD);
        }

        /// @dev transfer any native token received as dust to the to address
        if (address(this).balance > 0)
            payable(to).transfer(address(this).balance);
    }
}

File 8 of 24 : IBentoBoxMinimal.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

/// @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;

    function setMasterContractApproval(
        address user,
        address masterContract,
        bool approved,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

File 9 of 24 : ImmutableState.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "../interfaces/IImmutableState.sol";

/// @title ImmutableState
/// @notice Stores the immutable state
abstract contract ImmutableState is IImmutableState {
    /// @notice BentoBox token vault
    IBentoBoxMinimal public immutable override bentoBox;

    /// @notice Stargate Router for cross chain interaction
    IStargateRouter public immutable override stargateRouter;

    /// @notice Sushiswap Legacy AMM Factory
    address public immutable override factory;

    /// @notice Sushiswap Legacy AMM PairCodeHash
    bytes32 public immutable override pairCodeHash;

    constructor(
        IBentoBoxMinimal _bentoBox,
        IStargateRouter _stargateRouter,
        address _factory,
        bytes32 _pairCodeHash
    ) {
        bentoBox = _bentoBox;
        stargateRouter = _stargateRouter;
        factory = _factory;
        pairCodeHash = _pairCodeHash;
    }
}

File 10 of 24 : IImmutableState.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "./IBentoBoxMinimal.sol";
import "./stargate/IStargateRouter.sol";

interface IImmutableState {
    function bentoBox() external view returns (IBentoBoxMinimal);

    function stargateRouter() external view returns (IStargateRouter);

    function factory() external view returns (address);

    function pairCodeHash() external view returns (bytes32);
}

File 11 of 24 : IStargateRouter.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.11;

interface IStargateRouter {

    struct lzTxObj {
        uint256 dstGasForCall;
        uint256 dstNativeAmount;
        bytes dstNativeAddr;
    }

    function swap(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLD,
        uint256 _minAmountLD,
        lzTxObj memory _lzTxParams,
        bytes calldata _to,
        bytes calldata _payload
    ) external payable;

    function quoteLayerZeroFee(
        uint16 _dstChainId,
        uint8 _functionType,
        bytes calldata _toAddress,
        bytes calldata _transferAndCallPayload,
        lzTxObj memory _lzTxParams
    ) external view returns (uint256, uint256);
}

File 12 of 24 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

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

pragma solidity 0.8.11;

interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint256 value) external returns (bool);

    function withdraw(uint256) external;
}

File 14 of 24 : 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 15 of 24 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 16 of 24 : UniswapV2Library.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.5.0;

import "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Pair.sol";

import "./SafeMath.sol";

library UniswapV2Library {
    using SafeMathUniswap for uint256;

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

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

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

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

    // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256 amountOut) {
        require(amountIn > 0, "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "UniswapV2Library: INSUFFICIENT_LIQUIDITY"
        );
        uint256 amountInWithFee = amountIn.mul(997);
        uint256 numerator = amountInWithFee.mul(reserveOut);
        uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
        amountOut = numerator / denominator;
    }

    // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256 amountIn) {
        require(amountOut > 0, "UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "UniswapV2Library: INSUFFICIENT_LIQUIDITY"
        );
        uint256 numerator = reserveIn.mul(amountOut).mul(1000);
        uint256 denominator = reserveOut.sub(amountOut).mul(997);
        amountIn = (numerator / denominator).add(1);
    }

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

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

File 17 of 24 : IUniswapV2Pair.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

File 18 of 24 : SafeMath.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.6.12;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMathUniswap {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }
}

File 19 of 24 : ITridentSwapAdapter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "./ITridentRouter.sol";
import "../../adapters/BentoAdapter.sol";
import "../../adapters/TokenAdapter.sol";
import "../../base/ImmutableState.sol";

interface ITridentSwapAdapter {}

File 20 of 24 : ITridentRouter.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

import "./IPool.sol";
import "../IBentoBoxMinimal.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";

/// @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 21 of 24 : IPool.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.11;

/// @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 22 of 24 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20.sol";

File 23 of 24 : IStargateAdapter.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.11;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../../base/ImmutableState.sol";
import "../ISushiXSwap.sol";
import "./IStargateReceiver.sol";

interface IStargateAdapter {}

File 24 of 24 : IStargateReceiver.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.11;

interface IStargateReceiver {
    function sgReceive(
        uint16 _chainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        address _token,
        uint256 amountLD,
        bytes memory payload
    ) external;
}

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":"_bentoBox","type":"address"},{"internalType":"contract IStargateRouter","name":"_stargateRouter","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"bytes32","name":"_pairCodeHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotStargateRouter","type":"error"},{"inputs":[],"name":"TooLittleReceived","type":"error"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"approveToStargateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bentoBox","outputs":[{"internalType":"contract IBentoBoxMinimal","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"actions","type":"uint8[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"datas","type":"bytes[]"}],"name":"cook","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint8","name":"_functionType","type":"uint8"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_gas","type":"uint256"},{"internalType":"uint256","name":"_dustAmount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"sgReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stargateRouter","outputs":[{"internalType":"contract IStargateRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b5060405162004ca038038062004ca08339810160408190526200003591620000ca565b6001600160a01b03808516608081905281851660a05290831660c05260e08290526040805163577268d960e11b8152905163aee4d1b29160048082019260009290919082900301818387803b1580156200008e57600080fd5b505af1158015620000a3573d6000803e3d6000fd5b505050505050505062000124565b6001600160a01b0381168114620000c757600080fd5b50565b60008060008060808587031215620000e157600080fd5b8451620000ee81620000b1565b60208601519094506200010181620000b1565b60408601519093506200011481620000b1565b6060959095015193969295505050565b60805160a05160c05160e051614a7f62000221600039600081816101450152818161138c015281816114af0152612b3b0152600081816101db015281816113690152818161145801528181612ad50152612b1801526000818161018701528181610a8101528181610c1401528181610e3c015261226801526000818160b20152818161030301528181610583015281816105ae0152818161079701528181610ee701528181610fc8015281816110940152818161115e01528181611682015281816116a9015281816116ea0152818161190f01528181611b2601528181611c6a01528181611e6a01528181611fdf01526121160152614a7f6000f3fe60806040526004361061007f5760003560e01c8063a9e56f3c1161004e578063a9e56f3c14610175578063ab8236f3146101a9578063c45a0155146101c9578063d1ac3535146101fd57600080fd5b8063656f3d641461008b5780636b2ace87146100a05780636ce4fe03146100fe5780639aab92481461013357600080fd5b3661008657005b600080fd5b61009e610099366004613704565b61021d565b005b3480156100ac57600080fd5b506100d47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561010a57600080fd5b5061011e61011936600461381c565b610a7c565b604080519283526020830191909152016100f5565b34801561013f57600080fd5b506101677f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100f5565b34801561018157600080fd5b506100d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156101b557600080fd5b5061009e6101c43660046138a3565b610bfc565b3480156101d557600080fd5b506100d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561020957600080fd5b5061009e610218366004613933565b610e20565b825160005b81811015610a7557600085828151811061023e5761023e613950565b60200260200101519050600060ff168160ff16141561036b57600080600080600088878151811061027157610271613950565b602002602001015180602001905181019061028c919061399f565b6040517fc0a47c9300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152851515604483015260ff851660648301526084820184905260a48201839052959a50939850919650945092507f00000000000000000000000000000000000000000000000000000000000000009091169063c0a47c939060c401600060405180830381600087803b15801561034957600080fd5b505af115801561035d573d6000803e3d6000fd5b505050505050505050610a6c565b60ff8116600114156103e25760008060008087868151811061038f5761038f613950565b60200260200101518060200190518101906103aa91906139f9565b93509350935093506103d984338585858e8c815181106103cc576103cc613950565b6020026020010151610e84565b50505050610a6c565b60ff81166002141561044557600080600080600088878151811061040857610408613950565b60200260200101518060200190518101906104239190613a41565b9450945094509450945061043b853386868686610f5f565b5050505050610a6c565b60ff8116600b141561049c57600080600086858151811061046857610468613950565b60200260200101518060200190518101906104839190613a9e565b9250925092506104948383836111be565b505050610a6c565b60ff8116600314156105e2576000806000808786815181106104c0576104c0613950565b60200260200101518060200190518101906104db91906139f9565b9350935093509350816000141561057d576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610556573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057a9190613ae1565b91505b6105a8847f0000000000000000000000000000000000000000000000000000000000000000846111e5565b6103d9847f00000000000000000000000000000000000000000000000000000000000000008585858e8c815181106103cc576103cc613950565b60ff8116600414156106ee57600080600086858151811061060557610605613950565b60200260200101518060200190518101906106209190613a9e565b92509250925080600014156106e35773ffffffffffffffffffffffffffffffffffffffff8316156106e0576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d99190613ae1565b90506106e3565b50475b6104948383836111e5565b60ff81166005141561081357600080600080600088878151811061071457610714613950565b602002602001015180602001905181019061072f9190613a41565b94509450945094509450826000148015610747575081155b15610805576040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301523060248301527f0000000000000000000000000000000000000000000000000000000000000000169063f7888aec90604401602060405180830381865afa1580156107de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108029190613ae1565b91505b61043b853086868686610f5f565b60ff8116600614156108645760008085848151811061083457610834613950565b602002602001015180602001905181019061084f9190613afa565b9150915061085d828261126b565b5050610a6c565b60ff8116600714156109825760008060008087868151811061088857610888613950565b60200260200101518060200190518101906108a39190613b34565b93509350935093506000846000141561096a57826000815181106108c9576108c9613950565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190613ae1565b9450600190505b6109778585858585611361565b505050505050610a6c565b60ff8116600814156109c85760008483815181106109a2576109a2613950565b60200260200101518060200190518101906109bd9190613c6d565b905061085d816115d5565b60ff811660091415610a145760008483815181106109e8576109e8613950565b6020026020010151806020019051810190610a039190613f9a565b9050610a0e816118ff565b50610a6c565b60ff8116600a1415610a6c57600080600080878681518110610a3857610a38613950565b6020026020010151806020019051810190610a539190614297565b9350935093509350610a6784848484612237565b505050505b50600101610222565b5050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630a512369898989604051602001610af9919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b60405160208183030381529060405287604051602001610b19919061440a565b60405160208183030381529060405260405180606001604052808c81526020018b81526020018d604051602001610b7b919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152506040518663ffffffff1660e01b8152600401610bad959493929190614446565b6040805180830381865afa158015610bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bed919061449e565b90999098509650505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c6b576040517f8c66bf5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008084806020019051810190610c8591906144c2565b6040517f656f3d6400000000000000000000000000000000000000000000000000000000815293975091955093509150309063656f3d6490610ccf90869086908690600401614608565b600060405180830381600087803b158015610ce957600080fd5b505af1925050508015610cfa575060015b610dca573d808015610d28576040519150601f19603f3d011682016040523d82523d6000602084013e610d2d565b606091505b506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526024820189905289169063a9059cbb906044016020604051808303816000875af1158015610da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc7919061464b565b50505b4715610e145760405173ffffffffffffffffffffffffffffffffffffffff8516904780156108fc02916000818181858888f19350505050158015610e12573d6000803e3d6000fd5b505b50505050505050505050565b610e8173ffffffffffffffffffffffffffffffffffffffff82167f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612463565b50565b6040517f02b9446c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152858116604483015260648201859052608482018490527f000000000000000000000000000000000000000000000000000000000000000016906302b9446c90839060a401604080518083038185885af1158015610f30573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610f55919061449e565b5050505050505050565b801561103b576040517f97da6d3000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152858116604483015260648201859052608482018490527f000000000000000000000000000000000000000000000000000000000000000016906397da6d309060a40160408051808303816000875af1158015611010573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611034919061449e565b50506111b6565b8215611102576040517fda5139ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201859052600060448301527f0000000000000000000000000000000000000000000000000000000000000000169063da5139ca90606401602060405180830381865afa1580156110db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ff9190613ae1565b91505b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015286811660248301528581166044830152606482018490527f0000000000000000000000000000000000000000000000000000000000000000169063f18d03cc90608401600060405180830381600087803b1580156111a257600080fd5b505af1158015610e14573d6000803e3d6000fd5b505050505050565b6111e073ffffffffffffffffffffffffffffffffffffffff8416338484612663565b505050565b73ffffffffffffffffffffffffffffffffffffffff831615611222576111e073ffffffffffffffffffffffffffffffffffffffff841683836126c1565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015611265573d6000803e3d6000fd5b50505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff831690632e1a7d4d9082906370a0823190602401602060405180830381865afa1580156112dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113019190613ae1565b6040518263ffffffff1660e01b815260040161131f91815260200190565b600060405180830381600087803b15801561133957600080fd5b505af115801561134d573d6000803e3d6000fd5b5050505061135d600082476111e5565b5050565b6000806113b07f000000000000000000000000000000000000000000000000000000000000000088877f0000000000000000000000000000000000000000000000000000000000000000612717565b905080600182516113c19190614695565b815181106113d1576113d1613950565b602002602001015191508582101561144a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f696e73756666696369656e742d616d6f756e742d6f757400000000000000000060448201526064015b60405180910390fd5b82156115c0576115c06114d37f00000000000000000000000000000000000000000000000000000000000000008760008151811061148a5761148a613950565b6020026020010151886001815181106114a5576114a5613950565b60200260200101517f00000000000000000000000000000000000000000000000000000000000000006128be565b866000815181106114e6576114e6613950565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561155c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115809190613ae1565b8760008151811061159357611593613950565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166126c19092919063ffffffff16565b6115cb8186866129d8565b5095945050505050565b60008160200151600014156117e15781516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116769190613ae1565b90506116a783600001517f0000000000000000000000000000000000000000000000000000000000000000836111e5565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302b9446c84600001517f0000000000000000000000000000000000000000000000000000000000000000866060015160008151811061172057611720613950565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606481018490526000608482015260a40160408051808303816000875af11580156117b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d9919061449e565b602085015250505b60608201515160005b818110156118ba578360600151818151811061180857611808613950565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1663627dd56a8560600151838151811061184557611845613950565b6020026020010151602001516040518263ffffffff1660e01b815260040161186d919061440a565b6020604051808303816000875af115801561188c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b09190613ae1565b92506001016117ea565b5082604001518210156118f9576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b80515160005b81811015611b0f577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f18d03cc8460000151838151811061195f5761195f613950565b602002602001015160000151308660000151858151811061198257611982613950565b602002602001015160200151876000015186815181106119a4576119a4613950565b6020908102919091010151606001516040517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff94851660048201529284166024840152921660448201526064810191909152608401600060405180830381600087803b158015611a3057600080fd5b505af1158015611a44573d6000803e3d6000fd5b5050505082600001518181518110611a5e57611a5e613950565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1663627dd56a84600001518381518110611a9b57611a9b613950565b6020026020010151608001516040518263ffffffff1660e01b8152600401611ac3919061440a565b6020604051808303816000875af1158015611ae2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b069190613ae1565b50600101611905565b505060208101515160005b81811015611e535760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7888aec85602001518481518110611b7657611b76613950565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015611bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c159190613ae1565b90506000611c256008600a6147cc565b85602001518481518110611c3b57611c3b613950565b60200260200101516040015167ffffffffffffffff1683611c5c91906147db565b611c669190614818565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f18d03cc86602001518581518110611cba57611cba613950565b6020026020010151600001513088602001518781518110611cdd57611cdd613950565b60209081029190910181015101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260648101849052608401600060405180830381600087803b158015611d6957600080fd5b505af1158015611d7d573d6000803e3d6000fd5b5050505084602001518381518110611d9757611d97613950565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1663627dd56a86602001518581518110611dd457611dd4613950565b6020026020010151606001516040518263ffffffff1660e01b8152600401611dfc919061440a565b6020604051808303816000875af1158015611e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3f9190613ae1565b505050611e4c8160010190565b9050611b1a565b505060408101515160005b818110156111e05760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7888aec85604001518481518110611eba57611eba613950565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015611f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f599190613ae1565b905083604001518281518110611f7157611f71613950565b602002602001015160600151811015611fb6576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83604001518281518110611fcc57611fcc613950565b60200260200101516040015115612114577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166397da6d308560400151848151811061202f5761202f613950565b602002602001015160000151308760400151868151811061205257612052613950565b60209081029190910181015101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152600060648201526084810184905260a40160408051808303816000875af11580156120e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210d919061449e565b505061222e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f18d03cc8560400151848151811061216657612166613950565b602002602001015160000151308760400151868151811061218957612189613950565b60209081029190910181015101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260648101849052608401600060405180830381600087803b15801561221557600080fd5b505af1158015612229573d6000803e3d6000fd5b505050505b50600101611e5e565b60008461010001518484846040516020016122559493929190614853565b60405160208183030381529060405290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc47876000015188604001518960600151338b60800151600014156123595760208c01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123549190613ae1565b61235f565b8b608001515b8c60a0015160405180606001604052808f610120015181526020018f60c0015181526020018f60e001516040516020016123c4919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508e60e00151604051602001612416919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528b6040518b63ffffffff1660e01b815260040161244a999897969594939291906148a8565b6000604051808303818588803b1580156111a257600080fd5b80158061250357506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190613ae1565b155b61258f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401611441565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526111e09084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612c15565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112659085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016125e1565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526111e09084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016125e1565b6060600283511015612785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056324c6962726172793a20494e56414c49445f5041544800006044820152606401611441565b825167ffffffffffffffff81111561279f5761279f61341b565b6040519080825280602002602001820160405280156127c8578160200160208202803683370190505b50905083816000815181106127df576127df613950565b60200260200101818152505060005b600184516127fc9190614695565b8110156128b5576000806128508887858151811061281c5761281c613950565b6020026020010151888660016128329190614933565b8151811061284257612842613950565b602002602001015188612d21565b9150915061287884848151811061286957612869613950565b60200260200101518383612e22565b84612884856001614933565b8151811061289457612894613950565b602002602001018181525050505080806128ad9061494b565b9150506127ee565b50949350505050565b60008060006128cd8686612f9c565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b166034820152919350915087906048016040516020818303038152906040528051906020012085604051602001612997939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120979650505050505050565b60005b600183516129e99190614695565b81101561126557600080848381518110612a0557612a05613950565b602002602001015185846001612a1b9190614933565b81518110612a2b57612a2b613950565b6020026020010151915091506000612a438383612f9c565b509050600087612a54866001614933565b81518110612a6457612a64613950565b602002602001015190506000808373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614612aac57826000612ab0565b6000835b91509150600060028a51612ac49190614695565b8810612ad05788612b11565b612b117f0000000000000000000000000000000000000000000000000000000000000000878c612b018c6002614933565b815181106114a5576114a5613950565b9050612b5f7f000000000000000000000000000000000000000000000000000000000000000088887f00000000000000000000000000000000000000000000000000000000000000006128be565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f84848460006040519080825280601f01601f191660200182016040528015612ba9576020820181803683370190505b506040518563ffffffff1660e01b8152600401612bc99493929190614984565b600060405180830381600087803b158015612be357600080fd5b505af1158015612bf7573d6000803e3d6000fd5b50505050505050505050508080612c0d9061494b565b9150506129db565b6000612c77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166131219092919063ffffffff16565b8051909150156111e05780806020019051810190612c95919061464b565b6111e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611441565b6000806000612d308686612f9c565b509050600080612d42898989896128be565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db091906149dd565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612e0f578082612e12565b81815b909a909950975050505050505050565b6000808411612eb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4960448201527f4e5055545f414d4f554e540000000000000000000000000000000000000000006064820152608401611441565b600083118015612ec35750600082115b612f4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4c60448201527f49515549444954590000000000000000000000000000000000000000000000006064820152608401611441565b6000612f5d856103e561313a565b90506000612f6b828561313a565b90506000612f8583612f7f886103e861313a565b906131ca565b9050612f918183614818565b979650505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561305b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f556e697377617056324c6962726172793a204944454e544943414c5f4144445260448201527f45535345530000000000000000000000000000000000000000000000000000006064820152608401611441565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610613095578284613098565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff821661311a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f4144445245535300006044820152606401611441565b9250929050565b60606131308484600085613242565b90505b9392505050565b600081158061315e5750828261315081836147db565b925061315c9083614818565b145b6131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f770000000000000000000000006044820152606401611441565b92915050565b6000826131d78382614933565b91508110156131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f770000000000000000000000006044820152606401611441565b6060824710156132d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611441565b73ffffffffffffffffffffffffffffffffffffffff85163b613352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611441565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161337b9190614a2d565b60006040518083038185875af1925050503d80600081146133b8576040519150601f19603f3d011682016040523d82523d6000602084013e6133bd565b606091505b5091509150612f91828286606083156133d7575081613133565b8251156133e75782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611441919061440a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561346d5761346d61341b565b60405290565b6040805190810167ffffffffffffffff8111828210171561346d5761346d61341b565b6040516060810167ffffffffffffffff8111828210171561346d5761346d61341b565b60405160a0810167ffffffffffffffff8111828210171561346d5761346d61341b565b604051610140810167ffffffffffffffff8111828210171561346d5761346d61341b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156135475761354761341b565b604052919050565b600067ffffffffffffffff8211156135695761356961341b565b5060051b60200190565b60ff81168114610e8157600080fd5b600082601f83011261359357600080fd5b813560206135a86135a38361354f565b613500565b82815260059290921b840181019181810190868411156135c757600080fd5b8286015b848110156135e257803583529183019183016135cb565b509695505050505050565b600067ffffffffffffffff8211156136075761360761341b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261364457600080fd5b81356136526135a3826135ed565b81815284602083860101111561366757600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261369557600080fd5b813560206136a56135a38361354f565b82815260059290921b840181019181810190868411156136c457600080fd5b8286015b848110156135e257803567ffffffffffffffff8111156136e85760008081fd5b6136f68986838b0101613633565b8452509183019183016136c8565b60008060006060848603121561371957600080fd5b833567ffffffffffffffff8082111561373157600080fd5b818601915086601f83011261374557600080fd5b813560206137556135a38361354f565b82815260059290921b8401810191818101908a84111561377457600080fd5b948201945b8386101561379b57853561378c81613573565b82529482019490820190613779565b975050870135925050808211156137b157600080fd5b6137bd87838801613582565b935060408601359150808211156137d357600080fd5b506137e086828701613684565b9150509250925092565b61ffff81168114610e8157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610e8157600080fd5b60008060008060008060c0878903121561383557600080fd5b8635613840816137ea565b9550602087013561385081613573565b94506040870135613860816137fa565b9350606087013592506080870135915060a087013567ffffffffffffffff81111561388a57600080fd5b61389689828a01613633565b9150509295509295509295565b60008060008060008060c087890312156138bc57600080fd5b86356138c7816137ea565b9550602087013567ffffffffffffffff808211156138e457600080fd5b6138f08a838b01613633565b96506040890135955060608901359150613909826137fa565b9093506080880135925060a0880135908082111561392657600080fd5b5061389689828a01613633565b60006020828403121561394557600080fd5b8135613133816137fa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805161398a816137fa565b919050565b8051801515811461398a57600080fd5b600080600080600060a086880312156139b757600080fd5b85516139c2816137fa565b94506139d06020870161398f565b935060408601516139e081613573565b6060870151608090970151959894975095949392505050565b60008060008060808587031215613a0f57600080fd5b8451613a1a816137fa565b6020860151909450613a2b816137fa565b6040860151606090960151949790965092505050565b600080600080600060a08688031215613a5957600080fd5b8551613a64816137fa565b6020870151909550613a75816137fa565b6040870151606088015191955093509150613a926080870161398f565b90509295509295909350565b600080600060608486031215613ab357600080fd5b8351613abe816137fa565b6020850151909350613acf816137fa565b80925050604084015190509250925092565b600060208284031215613af357600080fd5b5051919050565b60008060408385031215613b0d57600080fd5b8251613b18816137fa565b6020840151909250613b29816137fa565b809150509250929050565b60008060008060808587031215613b4a57600080fd5b845193506020808601519350604086015167ffffffffffffffff811115613b7057600080fd5b8601601f81018813613b8157600080fd5b8051613b8f6135a38261354f565b81815260059190911b8201830190838101908a831115613bae57600080fd5b928401925b82841015613bd5578351613bc6816137fa565b82529284019290840190613bb3565b8096505050505050613be96060860161397f565b905092959194509250565b60005b83811015613c0f578181015183820152602001613bf7565b838111156112655750506000910152565b600082601f830112613c3157600080fd5b8151613c3f6135a3826135ed565b818152846020838601011115613c5457600080fd5b613c65826020830160208701613bf4565b949350505050565b60006020808385031215613c8057600080fd5b825167ffffffffffffffff80821115613c9857600080fd5b9084019060808287031215613cac57600080fd5b613cb461344a565b8251613cbf816137fa565b8152828401518482015260408084015181830152606084015183811115613ce557600080fd5b80850194505087601f850112613cfa57600080fd5b8351613d086135a38261354f565b81815260059190911b8501860190868101908a831115613d2757600080fd5b8787015b83811015613dc157805187811115613d435760008081fd5b8801808d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001861315613d775760008081fd5b613d7f613473565b8a820151613d8c816137fa565b81528187015189811115613da05760008081fd5b613dae8f8d83860101613c20565b828d015250845250918801918801613d2b565b506060850152509198975050505050505050565b600082601f830112613de657600080fd5b81516020613df66135a38361354f565b82815260059290921b84018101918181019086841115613e1557600080fd5b8286015b848110156135e257805167ffffffffffffffff80821115613e3a5760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215613e735760008081fd5b613e7b61344a565b87840151613e88816137fa565b8152604084810151613e99816137fa565b828a01526060858101518581168114613eb25760008081fd5b83830152928501519284841115613ecb57600091508182fd5b613ed98e8b86890101613c20565b90830152508652505050918301918301613e19565b600082601f830112613eff57600080fd5b81516020613f0f6135a38361354f565b82815260079290921b84018101918181019086841115613f2e57600080fd5b8286015b848110156135e25760808189031215613f4b5760008081fd5b613f5361344a565b8151613f5e816137fa565b815281850151613f6d816137fa565b818601526040613f7e83820161398f565b9082015260608281015190820152835291830191608001613f32565b60006020808385031215613fad57600080fd5b825167ffffffffffffffff80821115613fc557600080fd5b9084019060608287031215613fd957600080fd5b613fe1613496565b825182811115613ff057600080fd5b8301601f8101881361400157600080fd5b805161400f6135a38261354f565b81815260059190911b8201860190868101908a83111561402e57600080fd5b8784015b838110156140f65780518781111561404957600080fd5b850160a0818e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001121561407d57600080fd5b6140856134b9565b8a820151614092816137fa565b815260408201516140a2816137fa565b818c01526140b26060830161398f565b60408201526080820151606082015260a0820151898111156140d45760008081fd5b6140e28f8d83860101613c20565b608083015250845250918801918801614032565b508452505050828401518281111561410d57600080fd5b61411988828601613dd5565b8583015250604083015193508184111561413257600080fd5b61413e87858501613eee565b60408201529695505050505050565b805161398a816137ea565b600082601f83011261416957600080fd5b815160206141796135a38361354f565b82815260059290921b8401810191818101908684111561419857600080fd5b8286015b848110156135e25780516141af81613573565b835291830191830161419c565b600082601f8301126141cd57600080fd5b815160206141dd6135a38361354f565b82815260059290921b840181019181810190868411156141fc57600080fd5b8286015b848110156135e25780518352918301918301614200565b600082601f83011261422857600080fd5b815160206142386135a38361354f565b82815260059290921b8401810191818101908684111561425757600080fd5b8286015b848110156135e257805167ffffffffffffffff81111561427b5760008081fd5b6142898986838b0101613c20565b84525091830191830161425b565b6000806000808486036101a08112156142af57600080fd5b610140808212156142bf57600080fd5b6142c76134dc565b91506142d28761414d565b82526142e06020880161397f565b602083015260408701516040830152606087015160608301526080870151608083015260a087015160a083015260c087015160c083015261432360e0880161397f565b60e083015261010061433681890161397f565b90830152610120878101519083015286015190945067ffffffffffffffff8082111561436157600080fd5b61436d88838901614158565b945061016087015191508082111561438457600080fd5b614390888389016141bc565b93506101808701519150808211156143a757600080fd5b506143b487828801614217565b91505092959194509250565b600081518084526143d8816020860160208601613bf4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061313360208301846143c0565b80518252602081015160208301526000604082015160606040850152613c6560608501826143c0565b61ffff8616815260ff8516602082015260a06040820152600061446c60a08301866143c0565b828103606084015261447e81866143c0565b90508281036080840152614492818561441d565b98975050505050505050565b600080604083850312156144b157600080fd5b505080516020909101519092909150565b600080600080608085870312156144d857600080fd5b84516144e3816137fa565b602086015190945067ffffffffffffffff8082111561450157600080fd5b61450d88838901614158565b9450604087015191508082111561452357600080fd5b61452f888389016141bc565b935060608701519150808211156143a757600080fd5b600081518084526020808501945080840160005b8381101561457857815160ff1687529582019590820190600101614559565b509495945050505050565b600081518084526020808501945080840160005b8381101561457857815187529582019590820190600101614597565b600081518084526020808501808196508360051b8101915082860160005b858110156145fb5782840389526145e98483516143c0565b988501989350908401906001016145d1565b5091979650505050505050565b60608152600061461b6060830186614545565b828103602084015261462d8186614583565b9050828103604084015261464181856145b3565b9695505050505050565b60006020828403121561465d57600080fd5b6131338261398f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156146a7576146a7614666565b500390565b600181815b8085111561470557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156146eb576146eb614666565b808516156146f857918102915b93841c93908002906146b1565b509250929050565b60008261471c575060016131c4565b81614729575060006131c4565b816001811461473f576002811461474957614765565b60019150506131c4565b60ff84111561475a5761475a614666565b50506001821b6131c4565b5060208310610133831016604e8410600b8410161715614788575081810a6131c4565b61479283836146ac565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156147c4576147c4614666565b029392505050565b600061313360ff84168361470d565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561481357614813614666565b500290565b60008261484e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006148826080830186614545565b82810360408401526148948186614583565b90508281036060840152612f9181856145b3565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c08401526148fa8184018761441d565b905082810360e084015261490e81866143c0565b905082810361010084015261492381856143c0565b9c9b505050505050505050505050565b6000821982111561494657614946614666565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561497d5761497d614666565b5060010190565b84815283602082015273ffffffffffffffffffffffffffffffffffffffff8316604082015260806060820152600061464160808301846143c0565b80516dffffffffffffffffffffffffffff8116811461398a57600080fd5b6000806000606084860312156149f257600080fd5b6149fb846149bf565b9250614a09602085016149bf565b9150604084015163ffffffff81168114614a2257600080fd5b809150509250925092565b60008251614a3f818460208701613bf4565b919091019291505056fea26469706673582212200a79e4e2a29d70c49c280640620c7f4796d1fae2586e8bec97fefb1280e6b79664736f6c634300080b0033000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061007f5760003560e01c8063a9e56f3c1161004e578063a9e56f3c14610175578063ab8236f3146101a9578063c45a0155146101c9578063d1ac3535146101fd57600080fd5b8063656f3d641461008b5780636b2ace87146100a05780636ce4fe03146100fe5780639aab92481461013357600080fd5b3661008657005b600080fd5b61009e610099366004613704565b61021d565b005b3480156100ac57600080fd5b506100d47f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c481565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561010a57600080fd5b5061011e61011936600461381c565b610a7c565b604080519283526020830191909152016100f5565b34801561013f57600080fd5b506101677f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100f5565b34801561018157600080fd5b506100d47f000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b81565b3480156101b557600080fd5b5061009e6101c43660046138a3565b610bfc565b3480156101d557600080fd5b506100d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561020957600080fd5b5061009e610218366004613933565b610e20565b825160005b81811015610a7557600085828151811061023e5761023e613950565b60200260200101519050600060ff168160ff16141561036b57600080600080600088878151811061027157610271613950565b602002602001015180602001905181019061028c919061399f565b6040517fc0a47c9300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152851515604483015260ff851660648301526084820184905260a48201839052959a50939850919650945092507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c49091169063c0a47c939060c401600060405180830381600087803b15801561034957600080fd5b505af115801561035d573d6000803e3d6000fd5b505050505050505050610a6c565b60ff8116600114156103e25760008060008087868151811061038f5761038f613950565b60200260200101518060200190518101906103aa91906139f9565b93509350935093506103d984338585858e8c815181106103cc576103cc613950565b6020026020010151610e84565b50505050610a6c565b60ff81166002141561044557600080600080600088878151811061040857610408613950565b60200260200101518060200190518101906104239190613a41565b9450945094509450945061043b853386868686610f5f565b5050505050610a6c565b60ff8116600b141561049c57600080600086858151811061046857610468613950565b60200260200101518060200190518101906104839190613a9e565b9250925092506104948383836111be565b505050610a6c565b60ff8116600314156105e2576000806000808786815181106104c0576104c0613950565b60200260200101518060200190518101906104db91906139f9565b9350935093509350816000141561057d576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610556573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057a9190613ae1565b91505b6105a8847f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4846111e5565b6103d9847f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c48585858e8c815181106103cc576103cc613950565b60ff8116600414156106ee57600080600086858151811061060557610605613950565b60200260200101518060200190518101906106209190613a9e565b92509250925080600014156106e35773ffffffffffffffffffffffffffffffffffffffff8316156106e0576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d99190613ae1565b90506106e3565b50475b6104948383836111e5565b60ff81166005141561081357600080600080600088878151811061071457610714613950565b602002602001015180602001905181019061072f9190613a41565b94509450945094509450826000148015610747575081155b15610805576040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301523060248301527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4169063f7888aec90604401602060405180830381865afa1580156107de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108029190613ae1565b91505b61043b853086868686610f5f565b60ff8116600614156108645760008085848151811061083457610834613950565b602002602001015180602001905181019061084f9190613afa565b9150915061085d828261126b565b5050610a6c565b60ff8116600714156109825760008060008087868151811061088857610888613950565b60200260200101518060200190518101906108a39190613b34565b93509350935093506000846000141561096a57826000815181106108c9576108c9613950565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190613ae1565b9450600190505b6109778585858585611361565b505050505050610a6c565b60ff8116600814156109c85760008483815181106109a2576109a2613950565b60200260200101518060200190518101906109bd9190613c6d565b905061085d816115d5565b60ff811660091415610a145760008483815181106109e8576109e8613950565b6020026020010151806020019051810190610a039190613f9a565b9050610a0e816118ff565b50610a6c565b60ff8116600a1415610a6c57600080600080878681518110610a3857610a38613950565b6020026020010151806020019051810190610a539190614297565b9350935093509350610a6784848484612237565b505050505b50600101610222565b5050505050565b6000807f000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b73ffffffffffffffffffffffffffffffffffffffff16630a512369898989604051602001610af9919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b60405160208183030381529060405287604051602001610b19919061440a565b60405160208183030381529060405260405180606001604052808c81526020018b81526020018d604051602001610b7b919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152506040518663ffffffff1660e01b8152600401610bad959493929190614446565b6040805180830381865afa158015610bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bed919061449e565b90999098509650505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b1614610c6b576040517f8c66bf5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008084806020019051810190610c8591906144c2565b6040517f656f3d6400000000000000000000000000000000000000000000000000000000815293975091955093509150309063656f3d6490610ccf90869086908690600401614608565b600060405180830381600087803b158015610ce957600080fd5b505af1925050508015610cfa575060015b610dca573d808015610d28576040519150601f19603f3d011682016040523d82523d6000602084013e610d2d565b606091505b506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526024820189905289169063a9059cbb906044016020604051808303816000875af1158015610da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc7919061464b565b50505b4715610e145760405173ffffffffffffffffffffffffffffffffffffffff8516904780156108fc02916000818181858888f19350505050158015610e12573d6000803e3d6000fd5b505b50505050505050505050565b610e8173ffffffffffffffffffffffffffffffffffffffff82167f000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612463565b50565b6040517f02b9446c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152858116604483015260648201859052608482018490527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c416906302b9446c90839060a401604080518083038185885af1158015610f30573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610f55919061449e565b5050505050505050565b801561103b576040517f97da6d3000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152858116604483015260648201859052608482018490527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c416906397da6d309060a40160408051808303816000875af1158015611010573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611034919061449e565b50506111b6565b8215611102576040517fda5139ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201859052600060448301527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4169063da5139ca90606401602060405180830381865afa1580156110db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ff9190613ae1565b91505b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015286811660248301528581166044830152606482018490527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4169063f18d03cc90608401600060405180830381600087803b1580156111a257600080fd5b505af1158015610e14573d6000803e3d6000fd5b505050505050565b6111e073ffffffffffffffffffffffffffffffffffffffff8416338484612663565b505050565b73ffffffffffffffffffffffffffffffffffffffff831615611222576111e073ffffffffffffffffffffffffffffffffffffffff841683836126c1565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015611265573d6000803e3d6000fd5b50505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff831690632e1a7d4d9082906370a0823190602401602060405180830381865afa1580156112dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113019190613ae1565b6040518263ffffffff1660e01b815260040161131f91815260200190565b600060405180830381600087803b15801561133957600080fd5b505af115801561134d573d6000803e3d6000fd5b5050505061135d600082476111e5565b5050565b6000806113b07f000000000000000000000000000000000000000000000000000000000000000088877f0000000000000000000000000000000000000000000000000000000000000000612717565b905080600182516113c19190614695565b815181106113d1576113d1613950565b602002602001015191508582101561144a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f696e73756666696369656e742d616d6f756e742d6f757400000000000000000060448201526064015b60405180910390fd5b82156115c0576115c06114d37f00000000000000000000000000000000000000000000000000000000000000008760008151811061148a5761148a613950565b6020026020010151886001815181106114a5576114a5613950565b60200260200101517f00000000000000000000000000000000000000000000000000000000000000006128be565b866000815181106114e6576114e6613950565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561155c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115809190613ae1565b8760008151811061159357611593613950565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166126c19092919063ffffffff16565b6115cb8186866129d8565b5095945050505050565b60008160200151600014156117e15781516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116769190613ae1565b90506116a783600001517f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4836111e5565b7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff166302b9446c84600001517f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4866060015160008151811061172057611720613950565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606481018490526000608482015260a40160408051808303816000875af11580156117b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d9919061449e565b602085015250505b60608201515160005b818110156118ba578360600151818151811061180857611808613950565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1663627dd56a8560600151838151811061184557611845613950565b6020026020010151602001516040518263ffffffff1660e01b815260040161186d919061440a565b6020604051808303816000875af115801561188c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b09190613ae1565b92506001016117ea565b5082604001518210156118f9576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50919050565b80515160005b81811015611b0f577f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663f18d03cc8460000151838151811061195f5761195f613950565b602002602001015160000151308660000151858151811061198257611982613950565b602002602001015160200151876000015186815181106119a4576119a4613950565b6020908102919091010151606001516040517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff94851660048201529284166024840152921660448201526064810191909152608401600060405180830381600087803b158015611a3057600080fd5b505af1158015611a44573d6000803e3d6000fd5b5050505082600001518181518110611a5e57611a5e613950565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1663627dd56a84600001518381518110611a9b57611a9b613950565b6020026020010151608001516040518263ffffffff1660e01b8152600401611ac3919061440a565b6020604051808303816000875af1158015611ae2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b069190613ae1565b50600101611905565b505060208101515160005b81811015611e535760007f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663f7888aec85602001518481518110611b7657611b76613950565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015611bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c159190613ae1565b90506000611c256008600a6147cc565b85602001518481518110611c3b57611c3b613950565b60200260200101516040015167ffffffffffffffff1683611c5c91906147db565b611c669190614818565b90507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663f18d03cc86602001518581518110611cba57611cba613950565b6020026020010151600001513088602001518781518110611cdd57611cdd613950565b60209081029190910181015101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260648101849052608401600060405180830381600087803b158015611d6957600080fd5b505af1158015611d7d573d6000803e3d6000fd5b5050505084602001518381518110611d9757611d97613950565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff1663627dd56a86602001518581518110611dd457611dd4613950565b6020026020010151606001516040518263ffffffff1660e01b8152600401611dfc919061440a565b6020604051808303816000875af1158015611e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3f9190613ae1565b505050611e4c8160010190565b9050611b1a565b505060408101515160005b818110156111e05760007f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663f7888aec85604001518481518110611eba57611eba613950565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015611f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f599190613ae1565b905083604001518281518110611f7157611f71613950565b602002602001015160600151811015611fb6576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83604001518281518110611fcc57611fcc613950565b60200260200101516040015115612114577f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff166397da6d308560400151848151811061202f5761202f613950565b602002602001015160000151308760400151868151811061205257612052613950565b60209081029190910181015101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152600060648201526084810184905260a40160408051808303816000875af11580156120e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210d919061449e565b505061222e565b7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663f18d03cc8560400151848151811061216657612166613950565b602002602001015160000151308760400151868151811061218957612189613950565b60209081029190910181015101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260648101849052608401600060405180830381600087803b15801561221557600080fd5b505af1158015612229573d6000803e3d6000fd5b505050505b50600101611e5e565b60008461010001518484846040516020016122559493929190614853565b60405160208183030381529060405290507f000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc47876000015188604001518960600151338b60800151600014156123595760208c01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123549190613ae1565b61235f565b8b608001515b8c60a0015160405180606001604052808f610120015181526020018f60c0015181526020018f60e001516040516020016123c4919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508e60e00151604051602001612416919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528b6040518b63ffffffff1660e01b815260040161244a999897969594939291906148a8565b6000604051808303818588803b1580156111a257600080fd5b80158061250357506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190613ae1565b155b61258f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401611441565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526111e09084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612c15565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112659085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016125e1565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526111e09084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016125e1565b6060600283511015612785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056324c6962726172793a20494e56414c49445f5041544800006044820152606401611441565b825167ffffffffffffffff81111561279f5761279f61341b565b6040519080825280602002602001820160405280156127c8578160200160208202803683370190505b50905083816000815181106127df576127df613950565b60200260200101818152505060005b600184516127fc9190614695565b8110156128b5576000806128508887858151811061281c5761281c613950565b6020026020010151888660016128329190614933565b8151811061284257612842613950565b602002602001015188612d21565b9150915061287884848151811061286957612869613950565b60200260200101518383612e22565b84612884856001614933565b8151811061289457612894613950565b602002602001018181525050505080806128ad9061494b565b9150506127ee565b50949350505050565b60008060006128cd8686612f9c565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b166034820152919350915087906048016040516020818303038152906040528051906020012085604051602001612997939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120979650505050505050565b60005b600183516129e99190614695565b81101561126557600080848381518110612a0557612a05613950565b602002602001015185846001612a1b9190614933565b81518110612a2b57612a2b613950565b6020026020010151915091506000612a438383612f9c565b509050600087612a54866001614933565b81518110612a6457612a64613950565b602002602001015190506000808373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614612aac57826000612ab0565b6000835b91509150600060028a51612ac49190614695565b8810612ad05788612b11565b612b117f0000000000000000000000000000000000000000000000000000000000000000878c612b018c6002614933565b815181106114a5576114a5613950565b9050612b5f7f000000000000000000000000000000000000000000000000000000000000000088887f00000000000000000000000000000000000000000000000000000000000000006128be565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f84848460006040519080825280601f01601f191660200182016040528015612ba9576020820181803683370190505b506040518563ffffffff1660e01b8152600401612bc99493929190614984565b600060405180830381600087803b158015612be357600080fd5b505af1158015612bf7573d6000803e3d6000fd5b50505050505050505050508080612c0d9061494b565b9150506129db565b6000612c77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166131219092919063ffffffff16565b8051909150156111e05780806020019051810190612c95919061464b565b6111e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611441565b6000806000612d308686612f9c565b509050600080612d42898989896128be565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db091906149dd565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612e0f578082612e12565b81815b909a909950975050505050505050565b6000808411612eb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4960448201527f4e5055545f414d4f554e540000000000000000000000000000000000000000006064820152608401611441565b600083118015612ec35750600082115b612f4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4c60448201527f49515549444954590000000000000000000000000000000000000000000000006064820152608401611441565b6000612f5d856103e561313a565b90506000612f6b828561313a565b90506000612f8583612f7f886103e861313a565b906131ca565b9050612f918183614818565b979650505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561305b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f556e697377617056324c6962726172793a204944454e544943414c5f4144445260448201527f45535345530000000000000000000000000000000000000000000000000000006064820152608401611441565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610613095578284613098565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff821661311a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f4144445245535300006044820152606401611441565b9250929050565b60606131308484600085613242565b90505b9392505050565b600081158061315e5750828261315081836147db565b925061315c9083614818565b145b6131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f770000000000000000000000006044820152606401611441565b92915050565b6000826131d78382614933565b91508110156131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f770000000000000000000000006044820152606401611441565b6060824710156132d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611441565b73ffffffffffffffffffffffffffffffffffffffff85163b613352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611441565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161337b9190614a2d565b60006040518083038185875af1925050503d80600081146133b8576040519150601f19603f3d011682016040523d82523d6000602084013e6133bd565b606091505b5091509150612f91828286606083156133d7575081613133565b8251156133e75782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611441919061440a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561346d5761346d61341b565b60405290565b6040805190810167ffffffffffffffff8111828210171561346d5761346d61341b565b6040516060810167ffffffffffffffff8111828210171561346d5761346d61341b565b60405160a0810167ffffffffffffffff8111828210171561346d5761346d61341b565b604051610140810167ffffffffffffffff8111828210171561346d5761346d61341b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156135475761354761341b565b604052919050565b600067ffffffffffffffff8211156135695761356961341b565b5060051b60200190565b60ff81168114610e8157600080fd5b600082601f83011261359357600080fd5b813560206135a86135a38361354f565b613500565b82815260059290921b840181019181810190868411156135c757600080fd5b8286015b848110156135e257803583529183019183016135cb565b509695505050505050565b600067ffffffffffffffff8211156136075761360761341b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261364457600080fd5b81356136526135a3826135ed565b81815284602083860101111561366757600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261369557600080fd5b813560206136a56135a38361354f565b82815260059290921b840181019181810190868411156136c457600080fd5b8286015b848110156135e257803567ffffffffffffffff8111156136e85760008081fd5b6136f68986838b0101613633565b8452509183019183016136c8565b60008060006060848603121561371957600080fd5b833567ffffffffffffffff8082111561373157600080fd5b818601915086601f83011261374557600080fd5b813560206137556135a38361354f565b82815260059290921b8401810191818101908a84111561377457600080fd5b948201945b8386101561379b57853561378c81613573565b82529482019490820190613779565b975050870135925050808211156137b157600080fd5b6137bd87838801613582565b935060408601359150808211156137d357600080fd5b506137e086828701613684565b9150509250925092565b61ffff81168114610e8157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610e8157600080fd5b60008060008060008060c0878903121561383557600080fd5b8635613840816137ea565b9550602087013561385081613573565b94506040870135613860816137fa565b9350606087013592506080870135915060a087013567ffffffffffffffff81111561388a57600080fd5b61389689828a01613633565b9150509295509295509295565b60008060008060008060c087890312156138bc57600080fd5b86356138c7816137ea565b9550602087013567ffffffffffffffff808211156138e457600080fd5b6138f08a838b01613633565b96506040890135955060608901359150613909826137fa565b9093506080880135925060a0880135908082111561392657600080fd5b5061389689828a01613633565b60006020828403121561394557600080fd5b8135613133816137fa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805161398a816137fa565b919050565b8051801515811461398a57600080fd5b600080600080600060a086880312156139b757600080fd5b85516139c2816137fa565b94506139d06020870161398f565b935060408601516139e081613573565b6060870151608090970151959894975095949392505050565b60008060008060808587031215613a0f57600080fd5b8451613a1a816137fa565b6020860151909450613a2b816137fa565b6040860151606090960151949790965092505050565b600080600080600060a08688031215613a5957600080fd5b8551613a64816137fa565b6020870151909550613a75816137fa565b6040870151606088015191955093509150613a926080870161398f565b90509295509295909350565b600080600060608486031215613ab357600080fd5b8351613abe816137fa565b6020850151909350613acf816137fa565b80925050604084015190509250925092565b600060208284031215613af357600080fd5b5051919050565b60008060408385031215613b0d57600080fd5b8251613b18816137fa565b6020840151909250613b29816137fa565b809150509250929050565b60008060008060808587031215613b4a57600080fd5b845193506020808601519350604086015167ffffffffffffffff811115613b7057600080fd5b8601601f81018813613b8157600080fd5b8051613b8f6135a38261354f565b81815260059190911b8201830190838101908a831115613bae57600080fd5b928401925b82841015613bd5578351613bc6816137fa565b82529284019290840190613bb3565b8096505050505050613be96060860161397f565b905092959194509250565b60005b83811015613c0f578181015183820152602001613bf7565b838111156112655750506000910152565b600082601f830112613c3157600080fd5b8151613c3f6135a3826135ed565b818152846020838601011115613c5457600080fd5b613c65826020830160208701613bf4565b949350505050565b60006020808385031215613c8057600080fd5b825167ffffffffffffffff80821115613c9857600080fd5b9084019060808287031215613cac57600080fd5b613cb461344a565b8251613cbf816137fa565b8152828401518482015260408084015181830152606084015183811115613ce557600080fd5b80850194505087601f850112613cfa57600080fd5b8351613d086135a38261354f565b81815260059190911b8501860190868101908a831115613d2757600080fd5b8787015b83811015613dc157805187811115613d435760008081fd5b8801808d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001861315613d775760008081fd5b613d7f613473565b8a820151613d8c816137fa565b81528187015189811115613da05760008081fd5b613dae8f8d83860101613c20565b828d015250845250918801918801613d2b565b506060850152509198975050505050505050565b600082601f830112613de657600080fd5b81516020613df66135a38361354f565b82815260059290921b84018101918181019086841115613e1557600080fd5b8286015b848110156135e257805167ffffffffffffffff80821115613e3a5760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215613e735760008081fd5b613e7b61344a565b87840151613e88816137fa565b8152604084810151613e99816137fa565b828a01526060858101518581168114613eb25760008081fd5b83830152928501519284841115613ecb57600091508182fd5b613ed98e8b86890101613c20565b90830152508652505050918301918301613e19565b600082601f830112613eff57600080fd5b81516020613f0f6135a38361354f565b82815260079290921b84018101918181019086841115613f2e57600080fd5b8286015b848110156135e25760808189031215613f4b5760008081fd5b613f5361344a565b8151613f5e816137fa565b815281850151613f6d816137fa565b818601526040613f7e83820161398f565b9082015260608281015190820152835291830191608001613f32565b60006020808385031215613fad57600080fd5b825167ffffffffffffffff80821115613fc557600080fd5b9084019060608287031215613fd957600080fd5b613fe1613496565b825182811115613ff057600080fd5b8301601f8101881361400157600080fd5b805161400f6135a38261354f565b81815260059190911b8201860190868101908a83111561402e57600080fd5b8784015b838110156140f65780518781111561404957600080fd5b850160a0818e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001121561407d57600080fd5b6140856134b9565b8a820151614092816137fa565b815260408201516140a2816137fa565b818c01526140b26060830161398f565b60408201526080820151606082015260a0820151898111156140d45760008081fd5b6140e28f8d83860101613c20565b608083015250845250918801918801614032565b508452505050828401518281111561410d57600080fd5b61411988828601613dd5565b8583015250604083015193508184111561413257600080fd5b61413e87858501613eee565b60408201529695505050505050565b805161398a816137ea565b600082601f83011261416957600080fd5b815160206141796135a38361354f565b82815260059290921b8401810191818101908684111561419857600080fd5b8286015b848110156135e25780516141af81613573565b835291830191830161419c565b600082601f8301126141cd57600080fd5b815160206141dd6135a38361354f565b82815260059290921b840181019181810190868411156141fc57600080fd5b8286015b848110156135e25780518352918301918301614200565b600082601f83011261422857600080fd5b815160206142386135a38361354f565b82815260059290921b8401810191818101908684111561425757600080fd5b8286015b848110156135e257805167ffffffffffffffff81111561427b5760008081fd5b6142898986838b0101613c20565b84525091830191830161425b565b6000806000808486036101a08112156142af57600080fd5b610140808212156142bf57600080fd5b6142c76134dc565b91506142d28761414d565b82526142e06020880161397f565b602083015260408701516040830152606087015160608301526080870151608083015260a087015160a083015260c087015160c083015261432360e0880161397f565b60e083015261010061433681890161397f565b90830152610120878101519083015286015190945067ffffffffffffffff8082111561436157600080fd5b61436d88838901614158565b945061016087015191508082111561438457600080fd5b614390888389016141bc565b93506101808701519150808211156143a757600080fd5b506143b487828801614217565b91505092959194509250565b600081518084526143d8816020860160208601613bf4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061313360208301846143c0565b80518252602081015160208301526000604082015160606040850152613c6560608501826143c0565b61ffff8616815260ff8516602082015260a06040820152600061446c60a08301866143c0565b828103606084015261447e81866143c0565b90508281036080840152614492818561441d565b98975050505050505050565b600080604083850312156144b157600080fd5b505080516020909101519092909150565b600080600080608085870312156144d857600080fd5b84516144e3816137fa565b602086015190945067ffffffffffffffff8082111561450157600080fd5b61450d88838901614158565b9450604087015191508082111561452357600080fd5b61452f888389016141bc565b935060608701519150808211156143a757600080fd5b600081518084526020808501945080840160005b8381101561457857815160ff1687529582019590820190600101614559565b509495945050505050565b600081518084526020808501945080840160005b8381101561457857815187529582019590820190600101614597565b600081518084526020808501808196508360051b8101915082860160005b858110156145fb5782840389526145e98483516143c0565b988501989350908401906001016145d1565b5091979650505050505050565b60608152600061461b6060830186614545565b828103602084015261462d8186614583565b9050828103604084015261464181856145b3565b9695505050505050565b60006020828403121561465d57600080fd5b6131338261398f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156146a7576146a7614666565b500390565b600181815b8085111561470557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156146eb576146eb614666565b808516156146f857918102915b93841c93908002906146b1565b509250929050565b60008261471c575060016131c4565b81614729575060006131c4565b816001811461473f576002811461474957614765565b60019150506131c4565b60ff84111561475a5761475a614666565b50506001821b6131c4565b5060208310610133831016604e8410600b8410161715614788575081810a6131c4565b61479283836146ac565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156147c4576147c4614666565b029392505050565b600061313360ff84168361470d565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561481357614813614666565b500290565b60008261484e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006148826080830186614545565b82810360408401526148948186614583565b90508281036060840152612f9181856145b3565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c08401526148fa8184018761441d565b905082810360e084015261490e81866143c0565b905082810361010084015261492381856143c0565b9c9b505050505050505050505050565b6000821982111561494657614946614666565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561497d5761497d614666565b5060010190565b84815283602082015273ffffffffffffffffffffffffffffffffffffffff8316604082015260806060820152600061464160808301846143c0565b80516dffffffffffffffffffffffffffff8116811461398a57600080fd5b6000806000606084860312156149f257600080fd5b6149fb846149bf565b9250614a09602085016149bf565b9150604084015163ffffffff81168114614a2257600080fd5b809150509250925092565b60008251614a3f818460208701613bf4565b919091019291505056fea26469706673582212200a79e4e2a29d70c49c280640620c7f4796d1fae2586e8bec97fefb1280e6b79664736f6c634300080b0033

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

000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _bentoBox (address): 0xc35DADB65012eC5796536bD9864eD8773aBc74C4
Arg [1] : _stargateRouter (address): 0xB0D502E938ed5f4df2E681fE6E419ff29631d62b
Arg [2] : _factory (address): 0x0000000000000000000000000000000000000000
Arg [3] : _pairCodeHash (bytes32): 0x0000000000000000000000000000000000000000000000000000000000000000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4
Arg [1] : 000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.