ETH Price: $3,563.69 (+6.82%)

Contract

0x1e8b6Ac39f8A33f46a6Eb2D1aCD1047B99180AD1
 
Transaction Hash
Method
Block
From
To
0x60808060195792942024-04-04 2:02:47237 days ago1712196167IN
 Create: PendleSwapL1
0 ETH0.1069189221.84403507

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
212801012024-11-27 15:52:1150 mins ago1732722731
0x1e8b6Ac3...B99180AD1
0 ETH
212801012024-11-27 15:52:1150 mins ago1732722731
0x1e8b6Ac3...B99180AD1
0 ETH
212801012024-11-27 15:52:1150 mins ago1732722731
0x1e8b6Ac3...B99180AD1
0 ETH
212749772024-11-26 22:41:2318 hrs ago1732660883
0x1e8b6Ac3...B99180AD1
0 ETH
212749772024-11-26 22:41:2318 hrs ago1732660883
0x1e8b6Ac3...B99180AD1
0 ETH
212749772024-11-26 22:41:2318 hrs ago1732660883
0x1e8b6Ac3...B99180AD1
0 ETH
212741732024-11-26 20:00:1120 hrs ago1732651211
0x1e8b6Ac3...B99180AD1
0.035633 ETH
212741732024-11-26 20:00:1120 hrs ago1732651211
0x1e8b6Ac3...B99180AD1
0.035633 ETH
212686052024-11-26 1:21:2339 hrs ago1732584083
0x1e8b6Ac3...B99180AD1
0 ETH
212686052024-11-26 1:21:2339 hrs ago1732584083
0x1e8b6Ac3...B99180AD1
0 ETH
212686052024-11-26 1:21:2339 hrs ago1732584083
0x1e8b6Ac3...B99180AD1
0 ETH
212636412024-11-25 8:40:352 days ago1732524035
0x1e8b6Ac3...B99180AD1
0.05707129 ETH
212636412024-11-25 8:40:352 days ago1732524035
0x1e8b6Ac3...B99180AD1
0.05707129 ETH
212635422024-11-25 8:20:472 days ago1732522847
0x1e8b6Ac3...B99180AD1
0 ETH
212635422024-11-25 8:20:472 days ago1732522847
0x1e8b6Ac3...B99180AD1
0 ETH
212635422024-11-25 8:20:472 days ago1732522847
0x1e8b6Ac3...B99180AD1
0 ETH
212633232024-11-25 7:36:592 days ago1732520219
0x1e8b6Ac3...B99180AD1
0.05810455 ETH
212633232024-11-25 7:36:592 days ago1732520219
0x1e8b6Ac3...B99180AD1
0.05810455 ETH
212625442024-11-25 5:00:352 days ago1732510835
0x1e8b6Ac3...B99180AD1
0 ETH
212625442024-11-25 5:00:352 days ago1732510835
0x1e8b6Ac3...B99180AD1
0 ETH
212625442024-11-25 5:00:352 days ago1732510835
0x1e8b6Ac3...B99180AD1
0 ETH
212620362024-11-25 3:18:352 days ago1732504715
0x1e8b6Ac3...B99180AD1
0 ETH
212620362024-11-25 3:18:352 days ago1732504715
0x1e8b6Ac3...B99180AD1
0 ETH
212620362024-11-25 3:18:352 days ago1732504715
0x1e8b6Ac3...B99180AD1
0 ETH
212617312024-11-25 2:17:352 days ago1732501055
0x1e8b6Ac3...B99180AD1
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PendleSwapL1

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
shanghai EvmVersion
File 1 of 27 : PendleSwap.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.17;

import "../../core/libraries/TokenHelper.sol";
import "./IPSwapAggregator.sol";
import "./kyberswap/l1-contracts/InputScalingHelper.sol";
import "./kyberswap/l2-contracts/InputScalingHelperL2.sol";
import "./oneinch/OneInchAggregationRouterHelper.sol";

abstract contract PendleSwapBase is IPSwapAggregator, TokenHelper, OneInchAggregationRouterHelper {
    using Address for address;

    function swap(address tokenIn, uint256 amountIn, SwapData calldata data) external payable {
        _safeApproveInf(tokenIn, data.extRouter);
        data.extRouter.functionCallWithValue(
            data.needScale ? _getScaledInputData(data.swapType, data.extCalldata, amountIn) : data.extCalldata,
            tokenIn == NATIVE ? amountIn : 0
        );
    }

    function _getScaledInputData(
        SwapType swapType,
        bytes calldata rawCallData,
        uint256 amountIn
    ) internal pure returns (bytes memory scaledCallData) {
        if (swapType == SwapType.KYBERSWAP) {
            scaledCallData = _getKyberScaledInputData(rawCallData, amountIn);
        } else if (swapType == SwapType.ONE_INCH) {
            scaledCallData = _get1inchScaledInputData(rawCallData, amountIn);
        } else {
            assert(false);
        }
    }

    function _getKyberScaledInputData(
        bytes calldata rawCallData,
        uint256 amountIn
    ) internal pure virtual returns (bytes memory scaledCallData);

    receive() external payable {}
}

contract PendleSwapL1 is PendleSwapBase {
    function _getKyberScaledInputData(
        bytes calldata rawCallData,
        uint256 amountIn
    ) internal pure override returns (bytes memory) {
        return InputScalingHelper._getScaledInputData(rawCallData, amountIn);
    }
}

contract PendleSwapL2 is PendleSwapBase {
    function _getKyberScaledInputData(
        bytes calldata rawCallData,
        uint256 amountIn
    ) internal pure override returns (bytes memory) {
        return InputScalingHelperL2._getScaledInputData(rawCallData, amountIn);
    }
}

File 2 of 27 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 3 of 27 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

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

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

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

File 4 of 27 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 5 of 27 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/IERC20Permit.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;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    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));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    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");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @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");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @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).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // 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 cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

File 6 of 27 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 7 of 27 : Errors.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

library Errors {
    // BulkSeller
    error BulkInsufficientSyForTrade(uint256 currentAmount, uint256 requiredAmount);
    error BulkInsufficientTokenForTrade(uint256 currentAmount, uint256 requiredAmount);
    error BulkInSufficientSyOut(uint256 actualSyOut, uint256 requiredSyOut);
    error BulkInSufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut);
    error BulkInsufficientSyReceived(uint256 actualBalance, uint256 requiredBalance);
    error BulkNotMaintainer();
    error BulkNotAdmin();
    error BulkSellerAlreadyExisted(address token, address SY, address bulk);
    error BulkSellerInvalidToken(address token, address SY);
    error BulkBadRateTokenToSy(uint256 actualRate, uint256 currentRate, uint256 eps);
    error BulkBadRateSyToToken(uint256 actualRate, uint256 currentRate, uint256 eps);

    // APPROX
    error ApproxFail();
    error ApproxParamsInvalid(uint256 guessMin, uint256 guessMax, uint256 eps);
    error ApproxBinarySearchInputInvalid(
        uint256 approxGuessMin,
        uint256 approxGuessMax,
        uint256 minGuessMin,
        uint256 maxGuessMax
    );

    // MARKET + MARKET MATH CORE
    error MarketExpired();
    error MarketZeroAmountsInput();
    error MarketZeroAmountsOutput();
    error MarketZeroLnImpliedRate();
    error MarketInsufficientPtForTrade(int256 currentAmount, int256 requiredAmount);
    error MarketInsufficientPtReceived(uint256 actualBalance, uint256 requiredBalance);
    error MarketInsufficientSyReceived(uint256 actualBalance, uint256 requiredBalance);
    error MarketZeroTotalPtOrTotalAsset(int256 totalPt, int256 totalAsset);
    error MarketExchangeRateBelowOne(int256 exchangeRate);
    error MarketProportionMustNotEqualOne();
    error MarketRateScalarBelowZero(int256 rateScalar);
    error MarketScalarRootBelowZero(int256 scalarRoot);
    error MarketProportionTooHigh(int256 proportion, int256 maxProportion);

    error OracleUninitialized();
    error OracleTargetTooOld(uint32 target, uint32 oldest);
    error OracleZeroCardinality();

    error MarketFactoryExpiredPt();
    error MarketFactoryInvalidPt();
    error MarketFactoryMarketExists();

    error MarketFactoryLnFeeRateRootTooHigh(uint80 lnFeeRateRoot, uint256 maxLnFeeRateRoot);
    error MarketFactoryOverriddenFeeTooHigh(uint80 overriddenFee, uint256 marketLnFeeRateRoot);
    error MarketFactoryReserveFeePercentTooHigh(uint8 reserveFeePercent, uint8 maxReserveFeePercent);
    error MarketFactoryZeroTreasury();
    error MarketFactoryInitialAnchorTooLow(int256 initialAnchor, int256 minInitialAnchor);
    error MFNotPendleMarket(address addr);

    // ROUTER
    error RouterInsufficientLpOut(uint256 actualLpOut, uint256 requiredLpOut);
    error RouterInsufficientSyOut(uint256 actualSyOut, uint256 requiredSyOut);
    error RouterInsufficientPtOut(uint256 actualPtOut, uint256 requiredPtOut);
    error RouterInsufficientYtOut(uint256 actualYtOut, uint256 requiredYtOut);
    error RouterInsufficientPYOut(uint256 actualPYOut, uint256 requiredPYOut);
    error RouterInsufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut);
    error RouterInsufficientSyRepay(uint256 actualSyRepay, uint256 requiredSyRepay);
    error RouterInsufficientPtRepay(uint256 actualPtRepay, uint256 requiredPtRepay);
    error RouterNotAllSyUsed(uint256 netSyDesired, uint256 netSyUsed);

    error RouterTimeRangeZero();
    error RouterCallbackNotPendleMarket(address caller);
    error RouterInvalidAction(bytes4 selector);
    error RouterInvalidFacet(address facet);

    error RouterKyberSwapDataZero();

    error SimulationResults(bool success, bytes res);

    // YIELD CONTRACT
    error YCExpired();
    error YCNotExpired();
    error YieldContractInsufficientSy(uint256 actualSy, uint256 requiredSy);
    error YCNothingToRedeem();
    error YCPostExpiryDataNotSet();
    error YCNoFloatingSy();

    // YieldFactory
    error YCFactoryInvalidExpiry();
    error YCFactoryYieldContractExisted();
    error YCFactoryZeroExpiryDivisor();
    error YCFactoryZeroTreasury();
    error YCFactoryInterestFeeRateTooHigh(uint256 interestFeeRate, uint256 maxInterestFeeRate);
    error YCFactoryRewardFeeRateTooHigh(uint256 newRewardFeeRate, uint256 maxRewardFeeRate);

    // SY
    error SYInvalidTokenIn(address token);
    error SYInvalidTokenOut(address token);
    error SYZeroDeposit();
    error SYZeroRedeem();
    error SYInsufficientSharesOut(uint256 actualSharesOut, uint256 requiredSharesOut);
    error SYInsufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut);

    // SY-specific
    error SYQiTokenMintFailed(uint256 errCode);
    error SYQiTokenRedeemFailed(uint256 errCode);
    error SYQiTokenRedeemRewardsFailed(uint256 rewardAccruedType0, uint256 rewardAccruedType1);
    error SYQiTokenBorrowRateTooHigh(uint256 borrowRate, uint256 borrowRateMax);

    error SYCurveInvalidPid();
    error SYCurve3crvPoolNotFound();

    error SYApeDepositAmountTooSmall(uint256 amountDeposited);
    error SYBalancerInvalidPid();
    error SYInvalidRewardToken(address token);

    error SYStargateRedeemCapExceeded(uint256 amountLpDesired, uint256 amountLpRedeemable);

    error SYBalancerReentrancy();

    error NotFromTrustedRemote(uint16 srcChainId, bytes path);

    error ApxETHNotEnoughBuffer();

    // Liquidity Mining
    error VCInactivePool(address pool);
    error VCPoolAlreadyActive(address pool);
    error VCZeroVePendle(address user);
    error VCExceededMaxWeight(uint256 totalWeight, uint256 maxWeight);
    error VCEpochNotFinalized(uint256 wTime);
    error VCPoolAlreadyAddAndRemoved(address pool);

    error VEInvalidNewExpiry(uint256 newExpiry);
    error VEExceededMaxLockTime();
    error VEInsufficientLockTime();
    error VENotAllowedReduceExpiry();
    error VEZeroAmountLocked();
    error VEPositionNotExpired();
    error VEZeroPosition();
    error VEZeroSlope(uint128 bias, uint128 slope);
    error VEReceiveOldSupply(uint256 msgTime);

    error GCNotPendleMarket(address caller);
    error GCNotVotingController(address caller);

    error InvalidWTime(uint256 wTime);
    error ExpiryInThePast(uint256 expiry);
    error ChainNotSupported(uint256 chainId);

    error FDTotalAmountFundedNotMatch(uint256 actualTotalAmount, uint256 expectedTotalAmount);
    error FDEpochLengthMismatch();
    error FDInvalidPool(address pool);
    error FDPoolAlreadyExists(address pool);
    error FDInvalidNewFinishedEpoch(uint256 oldFinishedEpoch, uint256 newFinishedEpoch);
    error FDInvalidStartEpoch(uint256 startEpoch);
    error FDInvalidWTimeFund(uint256 lastFunded, uint256 wTime);
    error FDFutureFunding(uint256 lastFunded, uint256 currentWTime);

    error BDInvalidEpoch(uint256 epoch, uint256 startTime);

    // Cross-Chain
    error MsgNotFromSendEndpoint(uint16 srcChainId, bytes path);
    error MsgNotFromReceiveEndpoint(address sender);
    error InsufficientFeeToSendMsg(uint256 currentFee, uint256 requiredFee);
    error ApproxDstExecutionGasNotSet();
    error InvalidRetryData();

    // GENERIC MSG
    error ArrayLengthMismatch();
    error ArrayEmpty();
    error ArrayOutOfBounds();
    error ZeroAddress();
    error FailedToSendEther();
    error InvalidMerkleProof();

    error OnlyLayerZeroEndpoint();
    error OnlyYT();
    error OnlyYCFactory();
    error OnlyWhitelisted();

    // Swap Aggregator
    error SAInsufficientTokenIn(address tokenIn, uint256 amountExpected, uint256 amountActual);
    error UnsupportedSelector(uint256 aggregatorType, bytes4 selector);
}

File 8 of 27 : TokenHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

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

abstract contract TokenHelper {
    using SafeERC20 for IERC20;

    address internal constant NATIVE = address(0);
    uint256 internal constant LOWER_BOUND_APPROVAL = type(uint96).max / 2; // some tokens use 96 bits for approval

    function _transferIn(address token, address from, uint256 amount) internal {
        if (token == NATIVE) require(msg.value == amount, "eth mismatch");
        else if (amount != 0) IERC20(token).safeTransferFrom(from, address(this), amount);
    }

    function _transferFrom(IERC20 token, address from, address to, uint256 amount) internal {
        if (amount != 0) token.safeTransferFrom(from, to, amount);
    }

    function _transferOut(address token, address to, uint256 amount) internal {
        if (amount == 0) return;
        if (token == NATIVE) {
            (bool success, ) = to.call{value: amount}("");
            require(success, "eth send failed");
        } else {
            IERC20(token).safeTransfer(to, amount);
        }
    }

    function _transferOut(address[] memory tokens, address to, uint256[] memory amounts) internal {
        uint256 numTokens = tokens.length;
        require(numTokens == amounts.length, "length mismatch");
        for (uint256 i = 0; i < numTokens; ) {
            _transferOut(tokens[i], to, amounts[i]);
            unchecked {
                i++;
            }
        }
    }

    function _selfBalance(address token) internal view returns (uint256) {
        return (token == NATIVE) ? address(this).balance : IERC20(token).balanceOf(address(this));
    }

    function _selfBalance(IERC20 token) internal view returns (uint256) {
        return token.balanceOf(address(this));
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev PLS PAY ATTENTION to tokens that requires the approval to be set to 0 before changing it
    function _safeApprove(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "Safe Approve");
    }

    function _safeApproveInf(address token, address to) internal {
        if (token == NATIVE) return;
        if (IERC20(token).allowance(address(this), to) < LOWER_BOUND_APPROVAL) {
            _safeApprove(token, to, 0);
            _safeApprove(token, to, type(uint256).max);
        }
    }

    function _wrap_unwrap_ETH(address tokenIn, address tokenOut, uint256 netTokenIn) internal {
        if (tokenIn == NATIVE) IWETH(tokenOut).deposit{value: netTokenIn}();
        else IWETH(tokenIn).withdraw(netTokenIn);
    }
}

File 9 of 27 : IWETH.sol
// SPDX-License-Identifier: GPL-3.0-or-later
/*
 * MIT License
 * ===========
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 */
pragma solidity ^0.8.0;

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

interface IWETH is IERC20 {
    event Deposit(address indexed dst, uint256 wad);
    event Withdrawal(address indexed src, uint256 wad);

    function deposit() external payable;

    function withdraw(uint256 wad) external;
}

File 10 of 27 : IPSwapAggregator.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

struct SwapData {
    SwapType swapType;
    address extRouter;
    bytes extCalldata;
    bool needScale;
}

enum SwapType {
    NONE,
    KYBERSWAP,
    ONE_INCH,
    // ETH_WETH not used in Aggregator
    ETH_WETH
}

interface IPSwapAggregator {
    function swap(address tokenIn, uint256 amountIn, SwapData calldata swapData) external payable;
}

File 11 of 27 : IAggregationExecutor.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface IAggregationExecutor {
    function callBytes(bytes calldata data) external payable; // 0xd9c45357

    // callbytes per swap sequence
    function swapSingleSequence(bytes calldata data) external;

    function finalTransactionProcessing(
        address tokenIn,
        address tokenOut,
        address to,
        bytes calldata destTokenFeeData
    ) external;
}

File 12 of 27 : IAggregationExecutorOptimistic.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface IAggregationExecutorOptimistic {
    event Exchange(address pair, uint256 amountOut, address output);

    struct Swap {
        bytes data;
        bytes4 functionSelector;
    }

    struct SwapCallbackData {
        bytes path;
        address payer;
    }

    struct SwapCallbackDataPath {
        address pool;
        address tokenIn;
        address tokenOut;
    }

    struct PositiveSlippageFeeData {
        uint256 partnerPSInfor; // [partnerReceiver (160 bit) + partnerPercent(96bits)]
        uint256 expectedReturnAmount; // [minimumPSAmount (128 bits) + expectedReturnAmount (128 bits)]
    }

    struct SwapExecutorDescription {
        Swap[][] swapSequences;
        address tokenIn;
        address tokenOut;
        address to;
        uint256 deadline;
        bytes positiveSlippageData;
    }

    function rescueFunds(address token, uint256 amount) external;

    function callBytes(bytes calldata data) external payable;

    function swapSingleSequence(bytes calldata data) external;

    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        address to,
        uint256 deadline,
        bytes memory positiveSlippageData
    ) external payable;

    function finalTransactionProcessing(
        address tokenIn,
        address tokenOut,
        address to,
        bytes calldata destTokenFeeData
    ) external;

    function updateExecutor(bytes4 functionSelector, address executor) external;

    function updateBatchExecutors(bytes4[] memory functionSelectors, address[] memory executors) external;
}

File 13 of 27 : IExecutorHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12;

interface IExecutorHelper {
    struct Swap {
        bytes data;
        bytes32 selectorAndFlags; // [selector (32 bits) + flags (224 bits)]; selector is 4 most significant bytes; flags are stored in 4 least significant bytes.
    }

    struct SwapExecutorDescription {
        Swap[][] swapSequences;
        address tokenIn;
        address tokenOut;
        uint256 minTotalAmountOut;
        address to;
        uint256 deadline;
        bytes positiveSlippageData;
    }

    struct UniSwap {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 collectAmount; // amount that should be transferred to the pool
        uint32 swapFee;
        uint32 feePrecision;
        uint32 tokenWeightInput;
    }

    struct StableSwap {
        address pool;
        address tokenFrom;
        address tokenTo;
        uint8 tokenIndexFrom;
        uint8 tokenIndexTo;
        uint256 dx;
        uint256 poolLength;
        address poolLp;
        bool isSaddle; // true: saddle, false: stable
    }

    struct CurveSwap {
        address pool;
        address tokenFrom;
        address tokenTo;
        int128 tokenIndexFrom;
        int128 tokenIndexTo;
        uint256 dx;
        bool usePoolUnderlying;
        bool useTriCrypto;
    }

    struct UniswapV3KSElastic {
        address recipient;
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount;
        uint160 sqrtPriceLimitX96;
        bool isUniV3; // true = UniV3, false = KSElastic
    }

    struct BalancerV2 {
        address vault;
        bytes32 poolId;
        address assetIn;
        address assetOut;
        uint256 amount;
    }

    struct DODO {
        address recipient;
        address pool;
        address tokenFrom;
        address tokenTo;
        uint256 amount;
        address sellHelper;
        bool isSellBase;
        bool isVersion2;
    }

    struct GMX {
        address vault;
        address tokenIn;
        address tokenOut;
        uint256 amount;
        address receiver;
    }

    struct Synthetix {
        address synthetixProxy;
        address tokenIn;
        address tokenOut;
        bytes32 sourceCurrencyKey;
        uint256 sourceAmount;
        bytes32 destinationCurrencyKey;
        bool useAtomicExchange;
    }

    struct Platypus {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 collectAmount; // amount that should be transferred to the pool
    }

    struct PSM {
        address router;
        address tokenIn;
        address tokenOut;
        uint256 amountIn;
        address recipient;
    }

    struct WSTETH {
        address pool;
        uint256 amount;
        bool isWrapping;
    }

    struct Maverick {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 swapAmount;
        uint256 sqrtPriceLimitD18;
    }

    struct SyncSwap {
        bytes _data;
        address vault;
        address tokenIn;
        address pool;
        uint256 collectAmount;
    }

    struct AlgebraV1 {
        address recipient;
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount;
        uint160 sqrtPriceLimitX96;
        uint256 senderFeeOnTransfer; // [ FoT_FLAG(1 bit) ... SENDER_ADDRESS(160 bits) ]
    }

    struct BalancerBatch {
        address vault;
        bytes32[] poolIds;
        address[] path; // swap path from assetIn to assetOut
        bytes[] userDatas;
        uint256 amountIn; // assetIn amount
    }

    struct Mantis {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 amount;
        address recipient;
    }

    struct IziSwap {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 swapAmount;
        int24 limitPoint;
    }

    struct TraderJoeV2 {
        address recipient;
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 collectAmount; // most significant 1 bit is to determine whether pool is v2.1, else v2.0
    }

    struct LevelFiV2 {
        address pool;
        address fromToken;
        address toToken;
        uint256 amountIn;
        uint256 minAmountOut;
        address recipient; // receive token out
    }

    struct GMXGLP {
        address rewardRouter;
        address stakedGLP;
        address glpManager;
        address yearnVault;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount;
        address recipient;
    }

    struct Vooi {
        address pool;
        address fromToken;
        address toToken;
        uint256 fromID;
        uint256 toID;
        uint256 fromAmount;
        address to;
    }

    struct VelocoreV2 {
        address vault;
        uint256 amount;
        address tokenIn;
        address tokenOut;
        address stablePool; // if not empty then use stable pool
        address wrapToken;
        bool isConvertFirst;
    }

    struct MaticMigrate {
        address pool;
        address tokenAddress; // should be POL
        uint256 amount;
        address recipient; // empty if migrate
    }

    struct Kokonut {
        address pool;
        uint256 dx;
        uint256 tokenIndexFrom;
        address fromToken;
        address toToken;
    }

    struct BalancerV1 {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 amount;
    }

    struct SwaapV2 {
        address router;
        uint256 amount;
        bytes data;
        address tokenIn;
        address tokenOut;
        address recipient;
    }

    struct ArbswapStable {
        address pool;
        uint256 dx;
        uint256 tokenIndexFrom;
        address tokenIn;
        address tokenOut;
    }

    struct BancorV2 {
        address pool;
        address[] swapPath;
        uint256 amount;
        address recipient;
    }

    struct Ambient {
        address pool;
        uint128 qty;
        address base;
        address quote;
        uint256 poolIdx;
        uint8 settleFlags;
    }

    struct UniV1 {
        address pool;
        uint256 amount;
        address tokenIn;
        address tokenOut;
        address recipient;
    }

    struct LighterV2 {
        address orderBook;
        uint256 amount;
        bool isAsk; // isAsk = orderBook.isAskOrder(orderId);
        address tokenIn;
        address tokenOut;
        address recipient;
    }

    struct EtherFiWeETH {
        uint256 amount;
        bool isWrapping;
    }

    struct Kelp {
        uint256 amount;
        address tokenIn;
    }

    struct EthenaSusde {
        uint256 amount;
        address recipient;
    }

    struct RocketPool {
        address pool;
        uint256 isDepositAndAmount; // 1 isDeposit + 127 empty + 128 amount token in
    }

    struct MakersDAI {
        uint256 isRedeemAndAmount; // 1 isRedeem + 127 empty + 128 amount token in
        address recipient;
    }

    struct Renzo {
        address pool;
        uint256 amount;
        address tokenIn;
        address tokenOut;
    }

    struct FrxETH {
        address pool;
        uint256 amount;
        address tokenOut;
    }

    struct SfrxETH {
        address pool;
        uint256 amount;
        address tokenOut;
        address recipient;
    }

    struct SfrxETHConvertor {
        address pool;
        uint256 isDepositAndAmount; // 1 isDeposit + 127 empty + 128 amount token in
        address tokenIn;
        address tokenOut;
        address recipient;
    }

    struct OriginETH {
        address pool;
        uint256 amount;
    }

    function executeUniswap(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeStableSwap(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeCurve(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeKSClassic(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeUniV3KSElastic(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeRfq(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBalV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeDODO(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeVelodrome(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeGMX(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executePlatypus(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeWrappedstETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeStEth(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSynthetix(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeHashflow(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executePSM(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeFrax(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeCamelot(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeKyberLimitOrder(
        bytes memory data,
        uint256 flagsAndPrevAmountOut
    ) external payable returns (uint256);

    function executeMaverick(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSyncSwap(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeAlgebraV1(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBalancerBatch(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeWombat(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeMantis(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeIziSwap(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeWooFiV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeTraderJoeV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executePancakeStableSwap(
        bytes memory data,
        uint256 flagsAndPrevAmountOut
    ) external payable returns (uint256);

    function executeLevelFiV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeGMXGLP(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeVooi(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeVelocoreV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeMaticMigrate(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSmardex(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSolidlyV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeKokonut(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBalancerV1(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSwaapV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeNomiswapStable(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeArbswapStable(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBancorV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBancorV3(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeAmbient(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeUniV1(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeNative(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBebop(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeLighterV2(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeEtherFieETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeEtherFiWeETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeKelp(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeRocketPool(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeEthenaSusde(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeMakersDAI(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeRenzo(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeWBETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeMantleETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeFrxETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSfrxETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeSfrxETHConvertor(
        bytes memory data,
        uint256 flagsAndPrevAmountOut
    ) external payable returns (uint256);

    function executeSwellETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeRswETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeStaderETHx(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeOriginETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executePrimeETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeMantleUsd(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeBedrockUniETH(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);

    function executeMaiPSM(bytes memory data, uint256 flagsAndPrevAmountOut) external payable returns (uint256);
}

File 14 of 27 : IExecutorHelperL2.sol
pragma solidity >=0.6.12;

interface IExecutorHelperL2 {
    struct Swap {
        bytes data;
        bytes4 functionSelector;
    }

    struct SwapExecutorDescription {
        Swap[][] swapSequences;
        address tokenIn;
        address tokenOut;
        uint256 minTotalAmountOut;
        address to;
        uint256 deadline;
        bytes positiveSlippageData;
    }

    struct UniSwap {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 collectAmount; // amount that should be transferred to the pool
        uint32 swapFee;
        uint32 feePrecision;
        uint32 tokenWeightInput;
    }

    struct StableSwap {
        address pool;
        address tokenFrom;
        address tokenTo;
        uint8 tokenIndexFrom;
        uint8 tokenIndexTo;
        uint256 dx;
        uint256 poolLength;
        address poolLp;
        bool isSaddle; // true: saddle, false: stable
    }

    struct CurveSwap {
        address pool;
        address tokenFrom;
        address tokenTo;
        int128 tokenIndexFrom;
        int128 tokenIndexTo;
        uint256 dx;
        bool usePoolUnderlying;
        bool useTriCrypto;
    }

    struct UniswapV3KSElastic {
        address recipient;
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount;
        uint160 sqrtPriceLimitX96;
        bool isUniV3; // true = UniV3, false = KSElastic
    }

    struct SwapCallbackData {
        bytes path;
        address payer;
    }

    struct SwapCallbackDataPath {
        address pool;
        address tokenIn;
        address tokenOut;
    }

    struct BalancerV2 {
        address vault;
        bytes32 poolId;
        address assetIn;
        address assetOut;
        uint256 amount;
    }

    struct DODO {
        address recipient;
        address pool;
        address tokenFrom;
        address tokenTo;
        uint256 amount;
        address sellHelper;
        bool isSellBase;
        bool isVersion2;
    }

    struct GMX {
        address vault;
        address tokenIn;
        address tokenOut;
        uint256 amount;
        address receiver;
    }

    struct Synthetix {
        address synthetixProxy;
        address tokenIn;
        address tokenOut;
        bytes32 sourceCurrencyKey;
        uint256 sourceAmount;
        bytes32 destinationCurrencyKey;
        bool useAtomicExchange;
    }

    struct WSTETH {
        address pool;
        uint256 amount;
        bool isWrapping;
    }

    struct Platypus {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 collectAmount; // amount that should be transferred to the pool
    }

    struct PSM {
        address router;
        address tokenIn;
        address tokenOut;
        uint256 amountIn;
        address recipient;
    }

    struct Maverick {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 swapAmount;
        uint256 sqrtPriceLimitD18;
    }

    /// @notice Struct for Sync Swap
    /// @param _data encode of (address, address, uint8) : (tokenIn, recipient, withdrawMode)
    ///  Withdraw with mode.
    // 0 = DEFAULT
    // 1 = UNWRAPPED
    // 2 = WRAPPED
    /// @param vault vault contract
    /// @param tokenIn token input to swap
    /// @param pool pool of SyncSwap
    /// @param collectAmount amount that should be transferred to the pool
    struct SyncSwap {
        bytes _data;
        address vault;
        address tokenIn;
        address pool;
        uint256 collectAmount;
    }

    struct AlgebraV1 {
        address recipient;
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount;
        uint160 sqrtPriceLimitX96;
        uint256 senderFeeOnTransfer; // [ FoT_FLAG(1 bit) ... SENDER_ADDRESS(160 bits) ]
    }

    struct BalancerBatch {
        address vault;
        bytes32[] poolIds;
        address[] path; // swap path from assetIn to assetOut
        bytes[] userDatas;
        uint256 amountIn; // assetIn amount
    }

    struct Mantis {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 amount;
        address recipient;
    }

    struct IziSwap {
        address pool;
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 swapAmount;
        int24 limitPoint;
    }

    struct TraderJoeV2 {
        address recipient;
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 collectAmount; // most significant 1 bit is to determine whether pool is v2.0, else v2.1
    }

    struct LevelFiV2 {
        address pool;
        address fromToken;
        address toToken;
        uint256 amountIn;
        uint256 minAmountOut;
        address recipient; // receive token out
    }

    struct GMXGLP {
        address rewardRouter;
        address stakedGLP;
        address glpManager;
        address yearnVault;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount;
        address recipient;
    }

    struct Vooi {
        address pool;
        address fromToken;
        address toToken;
        uint256 fromID;
        uint256 toID;
        uint256 fromAmount;
        address to;
    }

    struct VelocoreV2 {
        address vault;
        uint256 amount;
        address tokenIn;
        address tokenOut;
        address stablePool; // if not empty then use stable pool
        address wrapToken;
        bool isConvertFirst;
    }

    struct MaticMigrate {
        address pool;
        address tokenAddress; // should be POL
        uint256 amount;
        address recipient; // empty if migrate
    }

    struct Kokonut {
        address pool;
        uint256 dx;
        uint256 tokenIndexFrom;
        address fromToken;
        address toToken;
    }

    struct BalancerV1 {
        address pool;
        uint256 amount;
        address tokenIn;
        address tokenOut;
    }

    struct SwaapV2 {
        address router;
        uint256 amount;
        bytes data;
        address tokenIn;
        address tokenOut;
        address recipient;
    }

    struct ArbswapStable {
        address pool;
        uint256 dx;
        uint256 tokenIndexFrom;
        address tokenIn;
        address tokenOut;
    }

    struct BancorV2 {
        address pool;
        address[] swapPath;
        uint256 amount;
        address recipient;
    }

    struct Ambient {
        address pool;
        uint128 qty;
        address base;
        address quote;
        uint256 poolIdx;
        uint8 settleFlags;
    }

    struct LighterV2 {
        address orderBook;
        uint256 amount;
        bool isAsk; // isAsk = orderBook.isAskOrder(orderId);
        address tokenIn;
        address tokenOut;
        address recipient;
    }

    struct FrxETH {
        address pool;
        uint256 amount;
        address tokenOut;
    }

    function executeUniswap(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeKSClassic(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeVelodrome(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeFrax(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeCamelot(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeKyberLimitOrder(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeRfq(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeHashflow(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeStableSwap(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeCurve(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeUniV3KSElastic(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeBalV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeDODO(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeGMX(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeSynthetix(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeWrappedstETH(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeStEth(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executePlatypus(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executePSM(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeMaverick(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeSyncSwap(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeAlgebraV1(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeBalancerBatch(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeWombat(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeMantis(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeIziSwap(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeTraderJoeV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeLevelFiV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeGMXGLP(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeVooi(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeVelocoreV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeSmardex(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeSolidlyV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeKokonut(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeBalancerV1(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeSwaapV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeNomiswapStable(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeArbswapStable(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeBancorV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeBancorV3(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeAmbient(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeNative(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeLighterV2(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);

    function executeMaiPSM(
        uint256 index,
        bytes memory data,
        uint256 previousAmountOut,
        address tokenIn,
        bool getPoolOnly,
        address nextPool
    ) external payable returns (address tokenOut, uint256 tokenAmountOut, address pool);
}

File 15 of 27 : IMetaAggregationRouterV2.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IAggregationExecutor} from "./IAggregationExecutor.sol";

interface IMetaAggregationRouterV2 {
    struct SwapDescriptionV2 {
        IERC20 srcToken;
        IERC20 dstToken;
        address[] srcReceivers; // transfer src token to these addresses, default
        uint256[] srcAmounts;
        address[] feeReceivers;
        uint256[] feeAmounts;
        address dstReceiver;
        uint256 amount;
        uint256 minReturnAmount;
        uint256 flags;
        bytes permit;
    }

    /// @dev  use for swapGeneric and swap to avoid stack too deep
    struct SwapExecutionParams {
        address callTarget; // call this address
        address approveTarget; // approve this address if _APPROVE_FUND set
        bytes targetData;
        SwapDescriptionV2 desc;
        bytes clientData;
    }

    struct SimpleSwapData {
        address[] firstPools;
        uint256[] firstSwapAmounts;
        bytes[] swapDatas;
        uint256 deadline;
        bytes positiveSlippageData;
    }

    function swap(SwapExecutionParams calldata execution) external payable returns (uint256, uint256);

    function swapSimpleMode(
        IAggregationExecutor caller,
        SwapDescriptionV2 memory desc,
        bytes calldata executorData,
        bytes calldata clientData
    ) external returns (uint256, uint256);
}

File 16 of 27 : InputScalingHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IExecutorHelper} from "../interfaces/IExecutorHelper.sol";
import {IMetaAggregationRouterV2} from "../interfaces/IMetaAggregationRouterV2.sol";
import {ScalingDataLib} from "./ScalingDataLib.sol";

/* ----------------------------------------
.__   __.   ______   .___________. _______
|  \ |  |  /  __  \  |           ||   ____|
|   \|  | |  |  |  | `---|  |----`|  |__
|  . `  | |  |  |  |     |  |     |   __|
|  |\   | |  `--'  |     |  |     |  |____
|__| \__|  \______/      |__|     |_______|


Please use InputScalingHelperL2 contract for scaling data on Arbitrum, Optimism, Base

---------------------------------------- */

library InputScalingHelper {
    uint256 private constant _PARTIAL_FILL = 0x01;
    uint256 private constant _REQUIRES_EXTRA_ETH = 0x02;
    uint256 private constant _SHOULD_CLAIM = 0x04;
    uint256 private constant _BURN_FROM_MSG_SENDER = 0x08;
    uint256 private constant _BURN_FROM_TX_ORIGIN = 0x10;
    uint256 private constant _SIMPLE_SWAP = 0x20;

    // fee data in case taking in dest token
    struct PositiveSlippageFeeData {
        uint256 partnerPSInfor; // [partnerReceiver (160 bit) + partnerPercent(96bits)]
        uint256 expectedReturnAmount;
    }

    struct Swap {
        bytes data;
        bytes32 selectorAndFlags; // [selector (32 bits) + flags (224 bits)]; selector is 4 most significant bytes; flags are stored in 4 least significant bytes.
    }

    struct SimpleSwapData {
        address[] firstPools;
        uint256[] firstSwapAmounts;
        bytes[] swapDatas;
        uint256 deadline;
        bytes positiveSlippageData;
    }

    struct SwapExecutorDescription {
        Swap[][] swapSequences;
        address tokenIn;
        address tokenOut;
        address to;
        uint256 deadline;
        bytes positiveSlippageData;
    }

    function _getScaledInputData(bytes calldata inputData, uint256 newAmount) internal pure returns (bytes memory) {
        bytes4 selector = bytes4(inputData[:4]);
        bytes calldata dataToDecode = inputData[4:];

        if (selector == IMetaAggregationRouterV2.swap.selector) {
            IMetaAggregationRouterV2.SwapExecutionParams memory params = abi.decode(
                dataToDecode,
                (IMetaAggregationRouterV2.SwapExecutionParams)
            );

            (params.desc, params.targetData) = _getScaledInputDataV2(
                params.desc,
                params.targetData,
                newAmount,
                _flagsChecked(params.desc.flags, _SIMPLE_SWAP)
            );
            return abi.encodeWithSelector(selector, params);
        } else if (selector == IMetaAggregationRouterV2.swapSimpleMode.selector) {
            (
                address callTarget,
                IMetaAggregationRouterV2.SwapDescriptionV2 memory desc,
                bytes memory targetData,
                bytes memory clientData
            ) = abi.decode(dataToDecode, (address, IMetaAggregationRouterV2.SwapDescriptionV2, bytes, bytes));

            (desc, targetData) = _getScaledInputDataV2(desc, targetData, newAmount, true);
            return abi.encodeWithSelector(selector, callTarget, desc, targetData, clientData);
        } else {
            revert("InputScalingHelper: Invalid selector");
        }
    }

    function _getScaledInputDataV2(
        IMetaAggregationRouterV2.SwapDescriptionV2 memory desc,
        bytes memory executorData,
        uint256 newAmount,
        bool isSimpleMode
    ) internal pure returns (IMetaAggregationRouterV2.SwapDescriptionV2 memory, bytes memory) {
        uint256 oldAmount = desc.amount;
        if (oldAmount == newAmount) {
            return (desc, executorData);
        }

        // simple mode swap
        if (isSimpleMode) {
            return (
                _scaledSwapDescriptionV2(desc, oldAmount, newAmount),
                _scaledSimpleSwapData(executorData, oldAmount, newAmount)
            );
        }

        //normal mode swap
        return (
            _scaledSwapDescriptionV2(desc, oldAmount, newAmount),
            _scaledExecutorCallBytesData(executorData, oldAmount, newAmount)
        );
    }

    /// @dev Scale the swap description
    function _scaledSwapDescriptionV2(
        IMetaAggregationRouterV2.SwapDescriptionV2 memory desc,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (IMetaAggregationRouterV2.SwapDescriptionV2 memory) {
        desc.minReturnAmount = (desc.minReturnAmount * newAmount) / oldAmount;
        if (desc.minReturnAmount == 0) desc.minReturnAmount = 1;
        desc.amount = newAmount;

        uint256 nReceivers = desc.srcReceivers.length;
        for (uint256 i = 0; i < nReceivers; ) {
            desc.srcAmounts[i] = (desc.srcAmounts[i] * newAmount) / oldAmount;
            unchecked {
                ++i;
            }
        }
        return desc;
    }

    /// @dev Scale the executorData in case swapSimpleMode
    function _scaledSimpleSwapData(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        SimpleSwapData memory swapData = abi.decode(data, (SimpleSwapData));

        uint256 nPools = swapData.firstPools.length;
        for (uint256 i = 0; i < nPools; ) {
            swapData.firstSwapAmounts[i] = (swapData.firstSwapAmounts[i] * newAmount) / oldAmount;
            unchecked {
                ++i;
            }
        }
        swapData.positiveSlippageData = _scaledPositiveSlippageFeeData(
            swapData.positiveSlippageData,
            oldAmount,
            newAmount
        );
        return abi.encode(swapData);
    }

    /// @dev Scale the executorData in case normal swap
    function _scaledExecutorCallBytesData(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        SwapExecutorDescription memory executorDesc = abi.decode(data, (SwapExecutorDescription));
        executorDesc.positiveSlippageData = _scaledPositiveSlippageFeeData(
            executorDesc.positiveSlippageData,
            oldAmount,
            newAmount
        );

        uint256 nSequences = executorDesc.swapSequences.length;
        for (uint256 i = 0; i < nSequences; ) {
            Swap memory swap = executorDesc.swapSequences[i][0];
            bytes4 functionSelector = bytes4(swap.selectorAndFlags);

            if (functionSelector == IExecutorHelper.executeUniswap.selector) {
                swap.data = ScalingDataLib.newUniSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeStableSwap.selector) {
                swap.data = ScalingDataLib.newStableSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeCurve.selector) {
                swap.data = ScalingDataLib.newCurveSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeKSClassic.selector) {
                swap.data = ScalingDataLib.newKyberDMM(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeUniV3KSElastic.selector) {
                swap.data = ScalingDataLib.newUniV3ProMM(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeRfq.selector) {
                revert("InputScalingHelper: Can not scale RFQ swap");
            } else if (functionSelector == IExecutorHelper.executeBalV2.selector) {
                swap.data = ScalingDataLib.newBalancerV2(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeWrappedstETH.selector) {
                swap.data = ScalingDataLib.newWrappedstETHSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeStEth.selector) {
                swap.data = ScalingDataLib.newStETHSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeDODO.selector) {
                swap.data = ScalingDataLib.newDODO(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeVelodrome.selector) {
                swap.data = ScalingDataLib.newVelodrome(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeGMX.selector) {
                swap.data = ScalingDataLib.newGMX(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSynthetix.selector) {
                swap.data = ScalingDataLib.newSynthetix(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeHashflow.selector) {
                revert("InputScalingHelper: Can not scale Hasflow swap");
            } else if (functionSelector == IExecutorHelper.executeCamelot.selector) {
                swap.data = ScalingDataLib.newCamelot(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeKyberLimitOrder.selector) {
                revert("InputScalingHelper: Can not scale KyberLO swap");
            } else if (functionSelector == IExecutorHelper.executePSM.selector) {
                swap.data = ScalingDataLib.newPSM(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeFrax.selector) {
                swap.data = ScalingDataLib.newFrax(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executePlatypus.selector) {
                swap.data = ScalingDataLib.newPlatypus(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeMaverick.selector) {
                swap.data = ScalingDataLib.newMaverick(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSyncSwap.selector) {
                swap.data = ScalingDataLib.newSyncSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeAlgebraV1.selector) {
                swap.data = ScalingDataLib.newAlgebraV1(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeBalancerBatch.selector) {
                swap.data = ScalingDataLib.newBalancerBatch(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeWombat.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount); // @dev struct Mantis is used for both Wombat and Mantis because of same fields
            } else if (functionSelector == IExecutorHelper.executeMantis.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeIziSwap.selector) {
                swap.data = ScalingDataLib.newIziSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeWooFiV2.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount); // @dev using Mantis struct because WooFiV2 and Mantis have same fields
            } else if (functionSelector == IExecutorHelper.executeTraderJoeV2.selector) {
                swap.data = ScalingDataLib.newTraderJoeV2(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executePancakeStableSwap.selector) {
                swap.data = ScalingDataLib.newCurveSwap(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeLevelFiV2.selector) {
                swap.data = ScalingDataLib.newLevelFiV2(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeGMXGLP.selector) {
                swap.data = ScalingDataLib.newGMXGLP(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeVooi.selector) {
                swap.data = ScalingDataLib.newVooi(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeVelocoreV2.selector) {
                swap.data = ScalingDataLib.newVelocoreV2(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeMaticMigrate.selector) {
                swap.data = ScalingDataLib.newMaticMigrate(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSmardex.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount); // @dev using Mantis struct because Smardex and Mantis have same fields
            } else if (functionSelector == IExecutorHelper.executeSolidlyV2.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount); // @dev using Mantis struct because Solidly V2 and Mantis have same fields
            } else if (functionSelector == IExecutorHelper.executeKokonut.selector) {
                swap.data = ScalingDataLib.newKokonut(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeBalancerV1.selector) {
                swap.data = ScalingDataLib.newBalancerV1(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSwaapV2.selector) {
                revert("InputScalingHelper: Can not scale SwaapV2 swap");
            } else if (functionSelector == IExecutorHelper.executeNomiswapStable.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount); // @dev using Mantis struct because NomiswapV2 and Mantis have same fields
            } else if (functionSelector == IExecutorHelper.executeArbswapStable.selector) {
                swap.data = ScalingDataLib.newArbswapStable(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeBancorV2.selector) {
                swap.data = ScalingDataLib.newBancorV2(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeBancorV3.selector) {
                swap.data = ScalingDataLib.newMantis(swap.data, oldAmount, newAmount); // @dev using Mantis struct because Bancor V3 and Mantis have same fields
            } else if (functionSelector == IExecutorHelper.executeAmbient.selector) {
                swap.data = ScalingDataLib.newAmbient(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeNative.selector) {
                revert("InputScalingHelper: Can not scale Native swap");
            } else if (functionSelector == IExecutorHelper.executeLighterV2.selector) {
                swap.data = ScalingDataLib.newLighterV2(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeBebop.selector) {
                revert("InputScalingHelper: Can not scale Bebop swap");
            } else if (functionSelector == IExecutorHelper.executeUniV1.selector) {
                swap.data = ScalingDataLib.newUniV1(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeEtherFieETH.selector) {
                swap.data = ScalingDataLib.newEtherFieETH(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeEtherFiWeETH.selector) {
                swap.data = ScalingDataLib.newEtherFiWeETH(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeKelp.selector) {
                swap.data = ScalingDataLib.newKelp(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeEthenaSusde.selector) {
                swap.data = ScalingDataLib.newEthenaSusde(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeRocketPool.selector) {
                swap.data = ScalingDataLib.newRocketPool(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeMakersDAI.selector) {
                swap.data = ScalingDataLib.newMakersDAI(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeRenzo.selector) {
                swap.data = ScalingDataLib.newRenzo(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeWBETH.selector) {
                swap.data = ScalingDataLib.newEtherFieETH(swap.data, oldAmount, newAmount); // same etherfi eETH
            } else if (functionSelector == IExecutorHelper.executeMantleETH.selector) {
                swap.data = ScalingDataLib.newEtherFieETH(swap.data, oldAmount, newAmount); // same etherfi eETH
            } else if (functionSelector == IExecutorHelper.executeFrxETH.selector) {
                swap.data = ScalingDataLib.newFrxETH(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSfrxETH.selector) {
                swap.data = ScalingDataLib.newSfrxETH(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSfrxETHConvertor.selector) {
                swap.data = ScalingDataLib.newSfrxETHConvertor(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeSwellETH.selector) {
                swap.data = ScalingDataLib.newEtherFieETH(swap.data, oldAmount, newAmount); // same etherfi eETH
            } else if (functionSelector == IExecutorHelper.executeRswETH.selector) {
                swap.data = ScalingDataLib.newEtherFieETH(swap.data, oldAmount, newAmount); // same etherfi eETH
            } else if (functionSelector == IExecutorHelper.executeStaderETHx.selector) {
                swap.data = ScalingDataLib.newEthenaSusde(swap.data, oldAmount, newAmount); // same ethena susde
            } else if (functionSelector == IExecutorHelper.executeOriginETH.selector) {
                swap.data = ScalingDataLib.newOriginETH(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executePrimeETH.selector) {
                swap.data = ScalingDataLib.newOriginETH(swap.data, oldAmount, newAmount); // same originETH
            } else if (functionSelector == IExecutorHelper.executeMantleUsd.selector) {
                swap.data = ScalingDataLib.newMantleUsd(swap.data, oldAmount, newAmount);
            } else if (functionSelector == IExecutorHelper.executeBedrockUniETH.selector) {
                swap.data = ScalingDataLib.newEtherFieETH(swap.data, oldAmount, newAmount); // same etherfi eETH
            } else if (functionSelector == IExecutorHelper.executeMaiPSM.selector) {
                swap.data = ScalingDataLib.newFrxETH(swap.data, oldAmount, newAmount); // same frxeth
            } else {
                revert("AggregationExecutor: Dex type not supported");
            }
            unchecked {
                ++i;
            }
        }
        return abi.encode(executorDesc);
    }

    function _scaledPositiveSlippageFeeData(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory newData) {
        if (data.length > 32) {
            PositiveSlippageFeeData memory psData = abi.decode(data, (PositiveSlippageFeeData));
            uint256 left = uint256(psData.expectedReturnAmount >> 128);
            uint256 right = (uint256(uint128(psData.expectedReturnAmount)) * newAmount) / oldAmount;
            require(right <= type(uint128).max, "Exceeded type range");
            psData.expectedReturnAmount = right | (left << 128);
            data = abi.encode(psData);
        } else if (data.length == 32) {
            uint256 expectedReturnAmount = abi.decode(data, (uint256));
            uint256 left = uint256(expectedReturnAmount >> 128);
            uint256 right = (uint256(uint128(expectedReturnAmount)) * newAmount) / oldAmount;
            require(right <= type(uint128).max, "Exceeded type range");
            expectedReturnAmount = right | (left << 128);
            data = abi.encode(expectedReturnAmount);
        }
        return data;
    }

    function _flagsChecked(uint256 number, uint256 flag) internal pure returns (bool) {
        return number & flag != 0;
    }
}

File 17 of 27 : ScalingDataLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IExecutorHelper} from "../interfaces/IExecutorHelper.sol";

library ScalingDataLib {
    function newUniSwap(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.UniSwap memory uniSwap = abi.decode(data, (IExecutorHelper.UniSwap));
        uniSwap.collectAmount = (uniSwap.collectAmount * newAmount) / oldAmount;
        return abi.encode(uniSwap);
    }

    function newStableSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.StableSwap memory stableSwap = abi.decode(data, (IExecutorHelper.StableSwap));
        stableSwap.dx = (stableSwap.dx * newAmount) / oldAmount;
        return abi.encode(stableSwap);
    }

    function newCurveSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.CurveSwap memory curveSwap = abi.decode(data, (IExecutorHelper.CurveSwap));
        curveSwap.dx = (curveSwap.dx * newAmount) / oldAmount;
        return abi.encode(curveSwap);
    }

    function newKyberDMM(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.UniSwap memory kyberDMMSwap = abi.decode(data, (IExecutorHelper.UniSwap));
        kyberDMMSwap.collectAmount = (kyberDMMSwap.collectAmount * newAmount) / oldAmount;
        return abi.encode(kyberDMMSwap);
    }

    function newUniV3ProMM(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.UniswapV3KSElastic memory uniSwapV3ProMM = abi.decode(
            data,
            (IExecutorHelper.UniswapV3KSElastic)
        );
        uniSwapV3ProMM.swapAmount = (uniSwapV3ProMM.swapAmount * newAmount) / oldAmount;

        return abi.encode(uniSwapV3ProMM);
    }

    function newBalancerV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.BalancerV2 memory balancerV2 = abi.decode(data, (IExecutorHelper.BalancerV2));
        balancerV2.amount = (balancerV2.amount * newAmount) / oldAmount;
        return abi.encode(balancerV2);
    }

    function newDODO(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.DODO memory dodo = abi.decode(data, (IExecutorHelper.DODO));
        dodo.amount = (dodo.amount * newAmount) / oldAmount;
        return abi.encode(dodo);
    }

    function newVelodrome(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.UniSwap memory velodrome = abi.decode(data, (IExecutorHelper.UniSwap));
        velodrome.collectAmount = (velodrome.collectAmount * newAmount) / oldAmount;
        return abi.encode(velodrome);
    }

    function newGMX(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.GMX memory gmx = abi.decode(data, (IExecutorHelper.GMX));
        gmx.amount = (gmx.amount * newAmount) / oldAmount;
        return abi.encode(gmx);
    }

    function newSynthetix(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.Synthetix memory synthetix = abi.decode(data, (IExecutorHelper.Synthetix));
        synthetix.sourceAmount = (synthetix.sourceAmount * newAmount) / oldAmount;
        return abi.encode(synthetix);
    }

    function newCamelot(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.UniSwap memory camelot = abi.decode(data, (IExecutorHelper.UniSwap));
        camelot.collectAmount = (camelot.collectAmount * newAmount) / oldAmount;
        return abi.encode(camelot);
    }

    function newPlatypus(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Platypus memory platypus = abi.decode(data, (IExecutorHelper.Platypus));
        platypus.collectAmount = (platypus.collectAmount * newAmount) / oldAmount;
        return abi.encode(platypus);
    }

    function newWrappedstETHSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.WSTETH memory wstEthData = abi.decode(data, (IExecutorHelper.WSTETH));
        wstEthData.amount = (wstEthData.amount * newAmount) / oldAmount;
        return abi.encode(wstEthData);
    }

    function newPSM(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.PSM memory psm = abi.decode(data, (IExecutorHelper.PSM));
        psm.amountIn = (psm.amountIn * newAmount) / oldAmount;
        return abi.encode(psm);
    }

    function newFrax(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.UniSwap memory frax = abi.decode(data, (IExecutorHelper.UniSwap));
        frax.collectAmount = (frax.collectAmount * newAmount) / oldAmount;
        return abi.encode(frax);
    }

    function newStETHSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 amount = abi.decode(data, (uint256));
        amount = (amount * newAmount) / oldAmount;
        return abi.encode(amount);
    }

    function newMaverick(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Maverick memory maverick = abi.decode(data, (IExecutorHelper.Maverick));
        maverick.swapAmount = (maverick.swapAmount * newAmount) / oldAmount;
        return abi.encode(maverick);
    }

    function newSyncSwap(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.SyncSwap memory syncSwap = abi.decode(data, (IExecutorHelper.SyncSwap));
        syncSwap.collectAmount = (syncSwap.collectAmount * newAmount) / oldAmount;
        return abi.encode(syncSwap);
    }

    function newAlgebraV1(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.AlgebraV1 memory algebraV1Swap = abi.decode(data, (IExecutorHelper.AlgebraV1));
        algebraV1Swap.swapAmount = (algebraV1Swap.swapAmount * newAmount) / oldAmount;
        return abi.encode(algebraV1Swap);
    }

    function newBalancerBatch(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.BalancerBatch memory balancerBatch = abi.decode(data, (IExecutorHelper.BalancerBatch));
        balancerBatch.amountIn = (balancerBatch.amountIn * newAmount) / oldAmount;
        return abi.encode(balancerBatch);
    }

    function newMantis(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Mantis memory mantis = abi.decode(data, (IExecutorHelper.Mantis));
        mantis.amount = (mantis.amount * newAmount) / oldAmount;
        return abi.encode(mantis);
    }

    function newIziSwap(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.IziSwap memory iZi = abi.decode(data, (IExecutorHelper.IziSwap));
        iZi.swapAmount = (iZi.swapAmount * newAmount) / oldAmount;
        return abi.encode(iZi);
    }

    function newTraderJoeV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.TraderJoeV2 memory traderJoe = abi.decode(data, (IExecutorHelper.TraderJoeV2));

        // traderJoe.collectAmount; // most significant 1 bit is to determine whether pool is v2.1, else v2.0
        traderJoe.collectAmount =
            (traderJoe.collectAmount & (1 << 255)) |
            ((uint256((traderJoe.collectAmount << 1) >> 1) * newAmount) / oldAmount);
        return abi.encode(traderJoe);
    }

    function newLevelFiV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.LevelFiV2 memory levelFiV2 = abi.decode(data, (IExecutorHelper.LevelFiV2));
        levelFiV2.amountIn = (levelFiV2.amountIn * newAmount) / oldAmount;
        return abi.encode(levelFiV2);
    }

    function newGMXGLP(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.GMXGLP memory swapData = abi.decode(data, (IExecutorHelper.GMXGLP));
        swapData.swapAmount = (swapData.swapAmount * newAmount) / oldAmount;
        return abi.encode(swapData);
    }

    function newVooi(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Vooi memory vooi = abi.decode(data, (IExecutorHelper.Vooi));
        vooi.fromAmount = (vooi.fromAmount * newAmount) / oldAmount;
        return abi.encode(vooi);
    }

    function newVelocoreV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.VelocoreV2 memory velocorev2 = abi.decode(data, (IExecutorHelper.VelocoreV2));
        velocorev2.amount = (velocorev2.amount * newAmount) / oldAmount;
        return abi.encode(velocorev2);
    }

    function newMaticMigrate(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.MaticMigrate memory maticMigrate = abi.decode(data, (IExecutorHelper.MaticMigrate));
        maticMigrate.amount = (maticMigrate.amount * newAmount) / oldAmount;
        return abi.encode(maticMigrate);
    }

    function newKokonut(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Kokonut memory kokonut = abi.decode(data, (IExecutorHelper.Kokonut));
        kokonut.dx = (kokonut.dx * newAmount) / oldAmount;
        return abi.encode(kokonut);
    }

    function newBalancerV1(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.BalancerV1 memory balancerV1 = abi.decode(data, (IExecutorHelper.BalancerV1));
        balancerV1.amount = (balancerV1.amount * newAmount) / oldAmount;
        return abi.encode(balancerV1);
    }

    function newArbswapStable(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.ArbswapStable memory arbswapStable = abi.decode(data, (IExecutorHelper.ArbswapStable));
        arbswapStable.dx = (arbswapStable.dx * newAmount) / oldAmount;
        return abi.encode(arbswapStable);
    }

    function newBancorV2(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.BancorV2 memory bancorV2 = abi.decode(data, (IExecutorHelper.BancorV2));
        bancorV2.amount = (bancorV2.amount * newAmount) / oldAmount;
        return abi.encode(bancorV2);
    }

    function newAmbient(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Ambient memory ambient = abi.decode(data, (IExecutorHelper.Ambient));
        ambient.qty = uint128((uint256(ambient.qty) * newAmount) / oldAmount);
        return abi.encode(ambient);
    }

    function newLighterV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.LighterV2 memory structData = abi.decode(data, (IExecutorHelper.LighterV2));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newUniV1(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.UniV1 memory structData = abi.decode(data, (IExecutorHelper.UniV1));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newEtherFieETH(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 depositAmount = abi.decode(data, (uint256));
        depositAmount = uint128((depositAmount * newAmount) / oldAmount);
        return abi.encode(depositAmount);
    }

    function newEtherFiWeETH(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.EtherFiWeETH memory structData = abi.decode(data, (IExecutorHelper.EtherFiWeETH));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newKelp(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Kelp memory structData = abi.decode(data, (IExecutorHelper.Kelp));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newEthenaSusde(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.EthenaSusde memory structData = abi.decode(data, (IExecutorHelper.EthenaSusde));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newRocketPool(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.RocketPool memory structData = abi.decode(data, (IExecutorHelper.RocketPool));

        uint128 _amount = uint128((uint256(uint128(structData.isDepositAndAmount)) * newAmount) / oldAmount);

        bool _isDeposit = (structData.isDepositAndAmount >> 255) == 1;

        // reset and create new variable for isDeposit and amount
        structData.isDepositAndAmount = 0;
        structData.isDepositAndAmount |= uint256(uint128(_amount));
        structData.isDepositAndAmount |= uint256(_isDeposit ? 1 : 0) << 255;

        return abi.encode(structData);
    }

    function newMakersDAI(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.MakersDAI memory structData = abi.decode(data, (IExecutorHelper.MakersDAI));
        uint128 _amount = uint128((uint256(uint128(structData.isRedeemAndAmount)) * newAmount) / oldAmount);

        bool _isRedeem = (structData.isRedeemAndAmount >> 255) == 1;

        // reset and create new variable for isRedeem and amount
        structData.isRedeemAndAmount = 0;
        structData.isRedeemAndAmount |= uint256(uint128(_amount));
        structData.isRedeemAndAmount |= uint256(_isRedeem ? 1 : 0) << 255;

        return abi.encode(structData);
    }

    function newRenzo(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.Renzo memory structData = abi.decode(data, (IExecutorHelper.Renzo));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newFrxETH(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.FrxETH memory structData = abi.decode(data, (IExecutorHelper.FrxETH));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newSfrxETH(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        IExecutorHelper.SfrxETH memory structData = abi.decode(data, (IExecutorHelper.SfrxETH));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newSfrxETHConvertor(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.SfrxETHConvertor memory structData = abi.decode(data, (IExecutorHelper.SfrxETHConvertor));

        uint128 _amount = uint128((uint256(uint128(structData.isDepositAndAmount)) * newAmount) / oldAmount);

        bool _isDeposit = (structData.isDepositAndAmount >> 255) == 1;

        // reset and create new variable for isDeposit and amount
        structData.isDepositAndAmount = 0;
        structData.isDepositAndAmount |= uint256(uint128(_amount));
        structData.isDepositAndAmount |= uint256(_isDeposit ? 1 : 0) << 255;

        return abi.encode(structData);
    }

    function newOriginETH(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelper.OriginETH memory structData = abi.decode(data, (IExecutorHelper.OriginETH));
        structData.amount = uint128((uint256(structData.amount) * newAmount) / oldAmount);
        return abi.encode(structData);
    }

    function newMantleUsd(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 isWrapAndAmount = abi.decode(data, (uint256));

        uint128 _amount = uint128((uint256(uint128(isWrapAndAmount)) * newAmount) / oldAmount);

        bool _isWrap = (isWrapAndAmount >> 255) == 1;

        // reset and create new variable for isWrap and amount
        isWrapAndAmount = 0;
        isWrapAndAmount |= uint256(uint128(_amount));
        isWrapAndAmount |= uint256(_isWrap ? 1 : 0) << 255;

        return abi.encode(isWrapAndAmount);
    }
}

File 18 of 27 : BytesHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library BytesHelper {
    function write16Bytes(bytes memory original, uint256 index, bytes16 value) internal pure returns (bytes memory) {
        assembly {
            let offset := add(original, add(index, 32))
            let val := mload(offset) // read 32 bytes [index : index + 32]
            val := and(val, not(0xffffffffffffffffffffffffffffffff00000000000000000000000000000000)) // clear [index : index + 16]
            val := or(val, value) // set 16 bytes to val above
            mstore(offset, val) // store to [index : index + 32]
        }
        return original;
    }

    function write16Bytes(bytes memory original, uint256 index, uint128 value) internal pure returns (bytes memory) {
        return write16Bytes(original, index, bytes16(value));
    }

    function write16Bytes(
        bytes memory original,
        uint256 index,
        uint256 value,
        string memory errorMsg
    ) internal pure returns (bytes memory) {
        require(value <= type(uint128).max, string(abi.encodePacked(errorMsg, "/Exceed compressed type range")));
        return write16Bytes(original, index, uint128(value));
    }
}

File 19 of 27 : CalldataReader.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library CalldataReader {
    /// @notice read the bytes value of data from a starting position and length
    /// @param data bytes array of data
    /// @param startByte starting position to read
    /// @param length length from starting position
    /// @return retVal value of the bytes
    /// @return (the next position to read from)
    function _calldataVal(
        bytes memory data,
        uint256 startByte,
        uint256 length
    ) internal pure returns (bytes memory retVal, uint256) {
        require(length + startByte <= data.length, "calldataVal trying to read beyond data size");
        uint256 loops = (length + 31) / 32;
        assembly {
            let m := mload(0x40)
            mstore(m, length)
            for {
                let i := 0
            } lt(i, loops) {
                i := add(1, i)
            } {
                mstore(add(m, mul(32, add(1, i))), mload(add(data, add(mul(32, add(1, i)), startByte))))
            }
            mstore(0x40, add(m, add(32, length)))
            retVal := m
        }
        return (retVal, length + startByte);
    }

    function _readBool(bytes memory data, uint256 startByte) internal pure returns (bool, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 1);
        return (bytes1(ret) > 0, startByte);
    }

    function _readUint8(bytes memory data, uint256 startByte) internal pure returns (uint8, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 1);
        return (uint8(bytes1(ret)), startByte);
    }

    function _readUint24(bytes memory data, uint256 startByte) internal pure returns (uint24, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 3);
        return (uint24(bytes3(ret)), startByte);
    }

    function _readUint32(bytes memory data, uint256 startByte) internal pure returns (uint32, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 4);
        return (uint32(bytes4(ret)), startByte);
    }

    function _readUint128(bytes memory data, uint256 startByte) internal pure returns (uint128, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 16);
        return (uint128(bytes16(ret)), startByte);
    }

    function _readUint160(bytes memory data, uint256 startByte) internal pure returns (uint160, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 20);
        return (uint160(bytes20(ret)), startByte);
    }

    /// @dev only when sure that the value of uint256 never exceed uint128
    function _readUint128AsUint256(bytes memory data, uint256 startByte) internal pure returns (uint256, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 16);
        return (uint256(uint128(bytes16(ret))), startByte);
    }

    function _readAddress(bytes memory data, uint256 startByte) internal pure returns (address, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 20);
        return (address(bytes20(ret)), startByte);
    }

    function _readBytes1(bytes memory data, uint256 startByte) internal pure returns (bytes1, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 1);
        return (bytes1(ret), startByte);
    }

    function _readBytes4(bytes memory data, uint256 startByte) internal pure returns (bytes4, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 4);
        return (bytes4(ret), startByte);
    }

    function _readBytes32(bytes memory data, uint256 startByte) internal pure returns (bytes32, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 32);
        return (bytes32(ret), startByte);
    }

    /// @dev length of bytes is currently limited to uint32
    function _readBytes(bytes memory data, uint256 startByte) internal pure returns (bytes memory b, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 4);
        uint256 length = uint256(uint32(bytes4(ret)));
        (b, startByte) = _calldataVal(data, startByte, length);
        return (b, startByte);
    }

    /// @dev length of bytes array is currently limited to uint8
    function _readBytesArray(
        bytes memory data,
        uint256 startByte
    ) internal pure returns (bytes[] memory bytesArray, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 1);
        uint256 length = uint256(uint8(bytes1(ret)));
        bytesArray = new bytes[](length);
        for (uint8 i = 0; i < length; ++i) {
            (bytesArray[i], startByte) = _readBytes(data, startByte);
        }
        return (bytesArray, startByte);
    }

    /// @dev length of address array is currently limited to uint8 to save bytes
    function _readAddressArray(
        bytes memory data,
        uint256 startByte
    ) internal pure returns (address[] memory addrs, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 1);
        uint256 length = uint256(uint8(bytes1(ret)));
        addrs = new address[](length);
        for (uint8 i = 0; i < length; ++i) {
            (addrs[i], startByte) = _readAddress(data, startByte);
        }
        return (addrs, startByte);
    }

    /// @dev length of uint array is currently limited to uint8 to save bytes
    /// @dev same as _readUint128AsUint256, only use when sure that value never exceed uint128
    function _readUint128ArrayAsUint256Array(
        bytes memory data,
        uint256 startByte
    ) internal pure returns (uint256[] memory, uint256) {
        bytes memory ret;
        (ret, startByte) = _calldataVal(data, startByte, 1);
        uint256 length = uint256(uint8(bytes1(ret)));
        uint256[] memory us = new uint256[](length);
        for (uint8 i = 0; i < length; ++i) {
            (us[i], startByte) = _readUint128AsUint256(data, startByte);
        }
        return (us, startByte);
    }
}

File 20 of 27 : CalldataWriter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IMetaAggregationRouterV2} from "../interfaces/IMetaAggregationRouterV2.sol";
import {IAggregationExecutorOptimistic as IExecutorHelperL2} from "../interfaces/IAggregationExecutorOptimistic.sol";
import {IExecutorHelper as IExecutorHelperL1} from "../interfaces/IExecutorHelper.sol";

library CalldataWriter {
    function writeSimpleSwapData(
        IMetaAggregationRouterV2.SimpleSwapData memory simpleSwapData
    ) internal pure returns (bytes memory shortData) {
        shortData = bytes.concat(shortData, _writeAddressArray(simpleSwapData.firstPools));
        shortData = bytes.concat(shortData, _writeUint256ArrayAsUint128Array(simpleSwapData.firstSwapAmounts));
        shortData = bytes.concat(shortData, _writeBytesArray(simpleSwapData.swapDatas));
        shortData = bytes.concat(shortData, bytes16(uint128(simpleSwapData.deadline)));
        shortData = bytes.concat(shortData, _writeBytes(simpleSwapData.positiveSlippageData));
    }

    /*
     ************************ AggregationExecutor ************************
     */
    function writeSwapExecutorDescription(
        IExecutorHelperL2.SwapExecutorDescription memory desc
    ) internal pure returns (bytes memory shortData) {
        // write Swap array
        uint8 lX = uint8(desc.swapSequences.length);
        shortData = bytes.concat(shortData, bytes1(lX));
        for (uint8 i = 0; i < lX; ++i) {
            uint8 lY = uint8(desc.swapSequences[i].length);
            shortData = bytes.concat(shortData, bytes1(lY));
            for (uint8 j = 0; j < lY; ++j) {
                shortData = bytes.concat(shortData, _writeSwap(desc.swapSequences[i][j]));
            }
        }

        // basic members
        shortData = bytes.concat(shortData, bytes20(desc.tokenIn));
        shortData = bytes.concat(shortData, bytes20(desc.tokenOut));
        shortData = bytes.concat(shortData, bytes20(desc.to));
        shortData = bytes.concat(shortData, bytes16(uint128(desc.deadline)));
        shortData = bytes.concat(shortData, _writeBytes(desc.positiveSlippageData));
    }

    function writeSimpleModeSwapDatas(
        bytes[] memory swapDatas,
        address tokenIn
    ) internal pure returns (bytes[] memory shortData) {
        uint8 len = uint8(swapDatas.length);
        for (uint8 i = 0; i < len; ++i) {
            swapDatas[i] = _writeSwapSingleSequence(swapDatas[i], tokenIn);
        }
        return (swapDatas);
    }

    function _writeSwapSingleSequence(
        bytes memory data,
        address tokenIn
    ) internal pure returns (bytes memory shortData) {
        IExecutorHelperL2.Swap[] memory swaps = abi.decode(data, (IExecutorHelperL2.Swap[]));

        uint8 len = uint8(swaps.length);
        shortData = bytes.concat(shortData, bytes1(len));
        for (uint8 i = 0; i < len; ++i) {
            shortData = bytes.concat(shortData, _writeSwap(swaps[i]));
        }
        shortData = bytes.concat(shortData, bytes20(tokenIn));
    }

    function _writeAddressArray(address[] memory addrs) internal pure returns (bytes memory data) {
        uint8 length = uint8(addrs.length);
        data = bytes.concat(data, bytes1(length));
        for (uint8 i = 0; i < length; ++i) {
            data = bytes.concat(data, bytes20(addrs[i]));
        }
        return data;
    }

    function _writeUint256ArrayAsUint128Array(uint256[] memory us) internal pure returns (bytes memory data) {
        uint8 length = uint8(us.length);
        data = bytes.concat(data, bytes1(length));
        for (uint8 i = 0; i < length; ++i) {
            data = bytes.concat(data, bytes16(uint128(us[i])));
        }
        return data;
    }

    function _writeBytes(bytes memory b) internal pure returns (bytes memory data) {
        uint32 length = uint32(b.length);
        data = bytes.concat(data, bytes4(length));
        data = bytes.concat(data, b);
        return data;
    }

    function _writeBytesArray(bytes[] memory bytesArray) internal pure returns (bytes memory data) {
        uint8 x = uint8(bytesArray.length);
        data = bytes.concat(data, bytes1(x));
        for (uint8 i; i < x; ++i) {
            uint32 length = uint32(bytesArray[i].length);
            data = bytes.concat(data, bytes4(length));
            data = bytes.concat(data, bytesArray[i]);
        }
        return data;
    }

    function _writeBytes32Array(bytes32[] memory bytesArray) internal pure returns (bytes memory data) {
        uint8 x = uint8(bytesArray.length);
        data = bytes.concat(data, bytes1(x));
        for (uint8 i; i < x; ++i) {
            data = bytes.concat(data, bytesArray[i]);
        }
        return data;
    }

    function _writeSwap(IExecutorHelperL2.Swap memory swap) internal pure returns (bytes memory shortData) {
        shortData = bytes.concat(shortData, _writeBytes(swap.data));
        shortData = bytes.concat(shortData, bytes1(uint8(uint32(swap.functionSelector))));
    }
}

File 21 of 27 : Common.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./CalldataReader.sol";

library Common {
    using CalldataReader for bytes;

    function _readPool(bytes memory data, uint256 startByte) internal pure returns (address, uint256) {
        uint24 poolId;
        address poolAddress;
        (poolId, startByte) = data._readUint24(startByte);
        if (poolId == 0) {
            (poolAddress, startByte) = data._readAddress(startByte);
        }
        return (poolAddress, startByte);
    }

    function _readRecipient(bytes memory data, uint256 startByte) internal pure returns (address, uint256) {
        uint8 recipientFlag;
        address recipient;
        (recipientFlag, startByte) = data._readUint8(startByte);
        if (recipientFlag != 2 && recipientFlag != 1) {
            (recipient, startByte) = data._readAddress(startByte);
        }
        return (recipient, startByte);
    }

    function _readBytes32Array(
        bytes memory data,
        uint256 startByte
    ) internal pure returns (bytes32[] memory bytesArray, uint256) {
        bytes memory ret;
        (ret, startByte) = data._calldataVal(startByte, 1);
        uint256 length = uint256(uint8(bytes1(ret)));
        bytesArray = new bytes32[](length);
        for (uint8 i = 0; i < length; ++i) {
            (bytesArray[i], startByte) = data._readBytes32(startByte);
        }
        return (bytesArray, startByte);
    }
}

File 22 of 27 : DexScaler.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./CalldataReader.sol";
import "../interfaces/IExecutorHelperL2.sol";
import {BytesHelper} from "./BytesHelper.sol";
import {Common} from "./Common.sol";

/// @title DexScaler
/// @notice Contain functions to scale DEX structs
/// @dev For this repo's scope, we only care about swap amounts, so we just need to decode until we get swap amounts
library DexScaler {
    using BytesHelper for bytes;
    using CalldataReader for bytes;
    using Common for bytes;

    function scaleUniSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;
        // decode
        (, startByte) = data._readPool(startByte);
        (, startByte) = data._readRecipient(startByte);
        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleUniSwap");
    }

    function scaleStableSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;
        (, startByte) = data._readPool(startByte);
        (, startByte) = data._readUint8(startByte);
        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleStableSwap");
    }

    function scaleCurveSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;
        bool canGetIndex;
        (canGetIndex, startByte) = data._readBool(0);
        (, startByte) = data._readPool(startByte);
        if (!canGetIndex) {
            (, startByte) = data._readAddress(startByte);
            (, startByte) = data._readUint8(startByte);
        }
        (, startByte) = data._readUint8(startByte);
        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleCurveSwap");
    }

    function scaleUniswapV3KSElastic(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;
        (, startByte) = data._readRecipient(startByte);
        (, startByte) = data._readPool(startByte);
        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(
                startByte,
                oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount,
                "scaleUniswapV3KSElastic"
            );
    }

    function scaleBalancerV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;
        (, startByte) = data._readPool(startByte);
        (, startByte) = data._readBytes32(startByte);
        (, startByte) = data._readUint8(startByte);
        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleBalancerV2");
    }

    function scaleDODO(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        uint256 startByte;
        (, startByte) = data._readRecipient(startByte);
        (, startByte) = data._readPool(startByte);
        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleDODO");
    }

    function scaleGMX(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        uint256 startByte;
        // decode
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleGMX");
    }

    function scaleSynthetix(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);
        (, startByte) = data._readBytes32(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleSynthetix");
    }

    function scaleWrappedstETH(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readPool(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(
                startByte,
                oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount,
                "scaleWrappedstETH"
            );
    }

    function scaleStETH(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        (uint256 swapAmount, ) = data._readUint128AsUint256(0);
        return data.write16Bytes(0, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleStETH");
    }

    function scalePlatypus(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);

        (, startByte) = data._readRecipient(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scalePlatypus");
    }

    function scalePSM(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scalePSM");
    }

    function scaleMaverick(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);

        (, startByte) = data._readRecipient(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleMaverick");
    }

    function scaleSyncSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readBytes(startByte);
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleSyncSwap");
    }

    function scaleAlgebraV1(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readRecipient(startByte);

        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readAddress(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);

        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleAlgebraV1");
    }

    function scaleBalancerBatch(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // decode
        (, startByte) = data._readPool(startByte);

        (, startByte) = data._readBytes32Array(startByte);
        (, startByte) = data._readAddressArray(startByte);
        (, startByte) = data._readBytesArray(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte);
        return
            data.write16Bytes(
                startByte,
                oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount,
                "scaleBalancerBatch"
            );
    }

    function scaleMantis(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readAddress(startByte); // tokenOut

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte); // amount
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleMantis");
    }

    function scaleIziSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readAddress(startByte); // tokenOut

        // recipient
        (, startByte) = data._readRecipient(startByte);

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte); // amount
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleIziSwap");
    }

    function scaleTraderJoeV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        // recipient
        (, startByte) = data._readRecipient(startByte);

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readAddress(startByte); // tokenOut

        (, startByte) = data._readBool(startByte); // isV2

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte); // amount
        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleTraderJoeV2");
    }

    function scaleLevelFiV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readAddress(startByte); // tokenOut

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte); // amount
        return
            data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleLevelFiV2");
    }

    function scaleGMXGLP(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readAddress(startByte); // yearnVault

        uint8 directionFlag;
        (directionFlag, startByte) = data._readUint8(startByte);
        if (directionFlag == 1) (, startByte) = data._readAddress(startByte); // tokenOut

        (uint256 swapAmount, ) = data._readUint128AsUint256(startByte); // amount
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (swapAmount * newAmount) / oldAmount, "scaleGMXGLP");
    }

    function scaleVooi(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readUint8(startByte); // toId

        (uint256 fromAmount, ) = data._readUint128AsUint256(startByte); // amount

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (fromAmount * newAmount) / oldAmount, "scaleVooi");
    }

    function scaleVelocoreV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (uint256 amount, ) = data._readUint128AsUint256(startByte); // amount

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (amount * newAmount) / oldAmount, "scaleVelocoreV2");
    }

    function scaleKokonut(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (uint256 amount, ) = data._readUint128AsUint256(startByte); // amount
        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (amount * newAmount) / oldAmount, "scaleKokonut");
    }

    function scaleBalancerV1(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (uint256 amount, ) = data._readUint128AsUint256(startByte); // amount

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (amount * newAmount) / oldAmount, "scaleBalancerV1");
    }

    function scaleArbswapStable(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (uint256 dx, ) = data._readUint128AsUint256(startByte); // dx

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (dx * newAmount) / oldAmount, "scaleArbswapStable");
    }

    function scaleBancorV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (, startByte) = data._readAddressArray(startByte); // swapPath

        (uint256 amount, ) = data._readUint128AsUint256(startByte); // amount

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (amount * newAmount) / oldAmount, "scaleBancorV2");
    }

    function scaleAmbient(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // pool

        (uint128 qty, ) = data._readUint128(startByte); // amount

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (qty * newAmount) / oldAmount, "scaleAmbient");
    }

    function scaleLighterV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        uint256 startByte;

        (, startByte) = data._readPool(startByte); // orderbook

        (uint128 amount, ) = data._readUint128(startByte); // amount

        return data.write16Bytes(startByte, oldAmount == 0 ? 0 : (amount * newAmount) / oldAmount, "scaleLighterV2");
    }
}

File 23 of 27 : ExecutorReader.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

library ExecutorReader {
    function readSwapExecutorDescription(bytes memory data) internal pure returns (bytes memory) {
        uint256 startByte = 0;
        IAggregationExecutorOptimistic.SwapExecutorDescription memory desc;

        // Swap array
        bytes memory ret;
        (ret, startByte) = CalldataReader._calldataVal(data, startByte, 1);
        uint256 lX = uint256(uint8(bytes1(ret)));
        desc.swapSequences = new IAggregationExecutorOptimistic.Swap[][](lX);
        for (uint8 i = 0; i < lX; ++i) {
            (ret, startByte) = CalldataReader._calldataVal(data, startByte, 1);
            uint256 lY = uint256(uint8(bytes1(ret)));
            desc.swapSequences[i] = new IAggregationExecutorOptimistic.Swap[](lY);
            for (uint8 j = 0; j < lY; ++j) {
                (desc.swapSequences[i][j], startByte) = _readSwap(data, startByte);
            }
        }

        // basic members
        (desc.tokenIn, startByte) = CalldataReader._readAddress(data, startByte);
        (desc.tokenOut, startByte) = CalldataReader._readAddress(data, startByte);
        (desc.to, startByte) = CalldataReader._readAddress(data, startByte);
        (desc.deadline, startByte) = CalldataReader._readUint128AsUint256(data, startByte);
        (desc.positiveSlippageData, startByte) = CalldataReader._readBytes(data, startByte);

        return abi.encode(desc);
    }

    function readSwapSingleSequence(
        bytes memory data
    ) internal pure returns (IAggregationExecutorOptimistic.Swap[] memory swaps, address tokenIn) {
        uint256 startByte = 0;
        bytes memory ret;
        (ret, startByte) = CalldataReader._calldataVal(data, startByte, 1);
        uint256 len = uint256(uint8(bytes1(ret)));
        swaps = new IAggregationExecutorOptimistic.Swap[](len);
        for (uint8 i = 0; i < len; ++i) {
            (swaps[i], startByte) = _readSwap(data, startByte);
        }
        (tokenIn, startByte) = CalldataReader._readAddress(data, startByte);
    }

    function _readSwap(
        bytes memory data,
        uint256 startByte
    ) internal pure returns (IAggregationExecutorOptimistic.Swap memory swap, uint256) {
        (swap.data, startByte) = CalldataReader._readBytes(data, startByte);
        bytes1 t;
        (t, startByte) = CalldataReader._readBytes1(data, startByte);
        swap.functionSelector = bytes4(uint32(uint8(t)));
        return (swap, startByte);
    }
}

File 24 of 27 : InputScalingHelperL2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IAggregationExecutorOptimistic as IExecutorHelperL2} from "../interfaces/IAggregationExecutorOptimistic.sol";
import {IExecutorHelper as IExecutorHelperL1} from "../interfaces/IExecutorHelper.sol";
import {IMetaAggregationRouterV2} from "../interfaces/IMetaAggregationRouterV2.sol";
import {ScalingDataL2Lib} from "./ScalingDataL2Lib.sol";
import {ExecutorReader} from "./ExecutorReader.sol";
import {CalldataWriter} from "./CalldataWriter.sol";

library InputScalingHelperL2 {
    using ExecutorReader for bytes;
    using ScalingDataL2Lib for bytes;

    uint256 private constant _PARTIAL_FILL = 0x01;
    uint256 private constant _REQUIRES_EXTRA_ETH = 0x02;
    uint256 private constant _SHOULD_CLAIM = 0x04;
    uint256 private constant _BURN_FROM_MSG_SENDER = 0x08;
    uint256 private constant _BURN_FROM_TX_ORIGIN = 0x10;
    uint256 private constant _SIMPLE_SWAP = 0x20;

    struct PositiveSlippageFeeData {
        uint256 partnerPSInfor;
        uint256 expectedReturnAmount;
    }

    enum DexIndex {
        UNI,
        KyberDMM,
        Velodrome,
        Fraxswap,
        Camelot,
        KyberLO,
        RFQ,
        Hashflow,
        StableSwap,
        Curve,
        UniswapV3KSElastic,
        BalancerV2,
        DODO,
        GMX,
        Synthetix,
        wstETH,
        stETH,
        Platypus,
        PSM,
        Maverick,
        SyncSwap,
        AlgebraV1,
        BalancerBatch,
        Mantis,
        Wombat,
        WooFiV2,
        iZiSwap,
        TraderJoeV2,
        KyberDSLO,
        LevelFiV2,
        GMXGLP,
        PancakeStableSwap,
        Vooi,
        VelocoreV2,
        Smardex,
        SolidlyV2,
        Kokonut,
        BalancerV1,
        SwaapV2,
        NomiswapStable,
        ArbswapStable,
        BancorV3,
        BancorV2,
        Ambient,
        Native,
        LighterV2,
        Bebop
    }

    function _getScaledInputData(bytes calldata inputData, uint256 newAmount) internal pure returns (bytes memory) {
        bytes4 selector = bytes4(inputData[:4]);
        bytes calldata dataToDecode = inputData[4:];

        if (selector == IMetaAggregationRouterV2.swap.selector) {
            IMetaAggregationRouterV2.SwapExecutionParams memory params = abi.decode(
                dataToDecode,
                (IMetaAggregationRouterV2.SwapExecutionParams)
            );

            (params.desc, params.targetData) = _getScaledInputDataV2(
                params.desc,
                params.targetData,
                newAmount,
                _flagsChecked(params.desc.flags, _SIMPLE_SWAP)
            );
            return abi.encodeWithSelector(selector, params);
        } else if (selector == IMetaAggregationRouterV2.swapSimpleMode.selector) {
            (
                address callTarget,
                IMetaAggregationRouterV2.SwapDescriptionV2 memory desc,
                bytes memory targetData,
                bytes memory clientData
            ) = abi.decode(dataToDecode, (address, IMetaAggregationRouterV2.SwapDescriptionV2, bytes, bytes));

            (desc, targetData) = _getScaledInputDataV2(desc, targetData, newAmount, true);
            return abi.encodeWithSelector(selector, callTarget, desc, targetData, clientData);
        } else {
            revert("InputScalingHelper: Invalid selector");
        }
    }

    function _getScaledInputDataV2(
        IMetaAggregationRouterV2.SwapDescriptionV2 memory desc,
        bytes memory executorData,
        uint256 newAmount,
        bool isSimpleMode
    ) internal pure returns (IMetaAggregationRouterV2.SwapDescriptionV2 memory, bytes memory) {
        uint256 oldAmount = desc.amount;
        if (oldAmount == newAmount) {
            return (desc, executorData);
        }

        // simple mode swap
        if (isSimpleMode) {
            return (
                _scaledSwapDescriptionV2(desc, oldAmount, newAmount),
                _scaledSimpleSwapData(executorData, oldAmount, newAmount)
            );
        }

        //normal mode swap
        return (
            _scaledSwapDescriptionV2(desc, oldAmount, newAmount),
            _scaledExecutorCallBytesData(executorData, oldAmount, newAmount)
        );
    }

    /// @dev Scale the swap description
    function _scaledSwapDescriptionV2(
        IMetaAggregationRouterV2.SwapDescriptionV2 memory desc,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (IMetaAggregationRouterV2.SwapDescriptionV2 memory) {
        desc.minReturnAmount = (desc.minReturnAmount * newAmount) / oldAmount;
        if (desc.minReturnAmount == 0) desc.minReturnAmount = 1;
        desc.amount = (desc.amount * newAmount) / oldAmount;

        uint256 nReceivers = desc.srcReceivers.length;
        for (uint256 i = 0; i < nReceivers; ) {
            desc.srcAmounts[i] = (desc.srcAmounts[i] * newAmount) / oldAmount;
            unchecked {
                ++i;
            }
        }
        return desc;
    }

    /// @dev Scale the executorData in case swapSimpleMode
    function _scaledSimpleSwapData(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IMetaAggregationRouterV2.SimpleSwapData memory simpleSwapData = abi.decode(
            data,
            (IMetaAggregationRouterV2.SimpleSwapData)
        );
        uint256 nPools = simpleSwapData.firstPools.length;
        address tokenIn;

        for (uint256 i = 0; i < nPools; ) {
            simpleSwapData.firstSwapAmounts[i] = (simpleSwapData.firstSwapAmounts[i] * newAmount) / oldAmount;

            IExecutorHelperL2.Swap[] memory dexData;

            (dexData, tokenIn) = simpleSwapData.swapDatas[i].readSwapSingleSequence();

            // only need to scale the first dex in each sequence
            if (dexData.length > 0) {
                dexData[0] = _scaleDexData(dexData[0], oldAmount, newAmount);
            }

            simpleSwapData.swapDatas[i] = CalldataWriter._writeSwapSingleSequence(abi.encode(dexData), tokenIn);

            unchecked {
                ++i;
            }
        }

        simpleSwapData.positiveSlippageData = _scaledPositiveSlippageFeeData(
            simpleSwapData.positiveSlippageData,
            oldAmount,
            newAmount
        );

        return abi.encode(simpleSwapData);
    }

    /// @dev Scale the executorData in case normal swap
    function _scaledExecutorCallBytesData(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        IExecutorHelperL2.SwapExecutorDescription memory executorDesc = abi.decode(
            data.readSwapExecutorDescription(),
            (IExecutorHelperL2.SwapExecutorDescription)
        );

        executorDesc.positiveSlippageData = _scaledPositiveSlippageFeeData(
            executorDesc.positiveSlippageData,
            oldAmount,
            newAmount
        );

        uint256 nSequences = executorDesc.swapSequences.length;
        for (uint256 i = 0; i < nSequences; ) {
            // only need to scale the first dex in each sequence
            IExecutorHelperL2.Swap memory swap = executorDesc.swapSequences[i][0];
            executorDesc.swapSequences[i][0] = _scaleDexData(swap, oldAmount, newAmount);
            unchecked {
                ++i;
            }
        }
        return CalldataWriter.writeSwapExecutorDescription(executorDesc);
    }

    function _scaledPositiveSlippageFeeData(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory newData) {
        if (data.length > 32) {
            PositiveSlippageFeeData memory psData = abi.decode(data, (PositiveSlippageFeeData));
            uint256 left = uint256(psData.expectedReturnAmount >> 128);
            uint256 right = (uint256(uint128(psData.expectedReturnAmount)) * newAmount) / oldAmount;
            require(right <= type(uint128).max, "_scaledPositiveSlippageFeeData/Exceeded type range");
            psData.expectedReturnAmount = right | (left << 128);
            data = abi.encode(psData);
        } else if (data.length == 32) {
            uint256 expectedReturnAmount = abi.decode(data, (uint256));
            uint256 left = uint256(expectedReturnAmount >> 128);
            uint256 right = (uint256(uint128(expectedReturnAmount)) * newAmount) / oldAmount;
            require(right <= type(uint128).max, "_scaledPositiveSlippageFeeData/Exceeded type range");
            expectedReturnAmount = right | (left << 128);
            data = abi.encode(expectedReturnAmount);
        }
        return data;
    }

    function _scaleDexData(
        IExecutorHelperL2.Swap memory swap,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (IExecutorHelperL2.Swap memory) {
        uint8 functionSelectorIndex = uint8(uint32(swap.functionSelector));

        if (DexIndex(functionSelectorIndex) == DexIndex.UNI) {
            swap.data = swap.data.newUniSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.StableSwap) {
            swap.data = swap.data.newStableSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Curve) {
            swap.data = swap.data.newCurveSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.KyberDMM) {
            swap.data = swap.data.newKyberDMM(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.UniswapV3KSElastic) {
            swap.data = swap.data.newUniswapV3KSElastic(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.RFQ) {
            revert("InputScalingHelper: Can not scale RFQ swap");
        } else if (DexIndex(functionSelectorIndex) == DexIndex.BalancerV2) {
            swap.data = swap.data.newBalancerV2(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.wstETH) {
            swap.data = swap.data.newWrappedstETHSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.stETH) {
            swap.data = swap.data.newStETHSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.DODO) {
            swap.data = swap.data.newDODO(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Velodrome) {
            swap.data = swap.data.newVelodrome(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.GMX) {
            swap.data = swap.data.newGMX(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Synthetix) {
            swap.data = swap.data.newSynthetix(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Hashflow) {
            revert("InputScalingHelper: Can not scale Hashflow swap");
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Camelot) {
            swap.data = swap.data.newCamelot(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.KyberLO) {
            revert("InputScalingHelper: Can not scale KyberLO swap");
        } else if (DexIndex(functionSelectorIndex) == DexIndex.PSM) {
            swap.data = swap.data.newPSM(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Fraxswap) {
            swap.data = swap.data.newFrax(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Platypus) {
            swap.data = swap.data.newPlatypus(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Maverick) {
            swap.data = swap.data.newMaverick(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.SyncSwap) {
            swap.data = swap.data.newSyncSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.AlgebraV1) {
            swap.data = swap.data.newAlgebraV1(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.BalancerBatch) {
            swap.data = swap.data.newBalancerBatch(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Mantis) {
            swap.data = swap.data.newMantis(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Wombat) {
            swap.data = swap.data.newMantis(oldAmount, newAmount); // @dev use identical calldata structure as Mantis
        } else if (DexIndex(functionSelectorIndex) == DexIndex.iZiSwap) {
            swap.data = swap.data.newIziSwap(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.TraderJoeV2) {
            swap.data = swap.data.newTraderJoeV2(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.WooFiV2) {
            swap.data = swap.data.newMantis(oldAmount, newAmount); // @dev use identical calldata structure as Mantis
        } else if (DexIndex(functionSelectorIndex) == DexIndex.KyberDSLO) {
            revert("InputScalingHelper: Can not scale KyberDSLO swap");
        } else if (DexIndex(functionSelectorIndex) == DexIndex.LevelFiV2) {
            swap.data = swap.data.newLevelFiV2(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.PancakeStableSwap) {
            swap.data = swap.data.newCurveSwap(oldAmount, newAmount); // @dev same encoded data as Curve
        } else if (DexIndex(functionSelectorIndex) == DexIndex.GMXGLP) {
            swap.data = swap.data.newGMXGLP(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Vooi) {
            swap.data = swap.data.newVooi(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.VelocoreV2) {
            swap.data = swap.data.newVelocoreV2(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Smardex) {
            swap.data = swap.data.newMantis(oldAmount, newAmount); // @dev use identical calldata structure as Mantis
        } else if (DexIndex(functionSelectorIndex) == DexIndex.SolidlyV2) {
            swap.data = swap.data.newMantis(oldAmount, newAmount); // @dev use identical calldata structure as Mantis
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Kokonut) {
            swap.data = swap.data.newKokonut(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.BalancerV1) {
            swap.data = swap.data.newBalancerV1(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.SwaapV2) {
            revert("InputScalingHelper: Can not scale SwaapV2 swap");
        } else if (DexIndex(functionSelectorIndex) == DexIndex.NomiswapStable) {
            swap.data = swap.data.newMantis(oldAmount, newAmount); // @dev use identical calldata structure as Mantis
        } else if (DexIndex(functionSelectorIndex) == DexIndex.ArbswapStable) {
            swap.data = swap.data.newArbswapStable(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.BancorV2) {
            swap.data = swap.data.newBancorV2(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.BancorV3) {
            swap.data = swap.data.newMantis(oldAmount, newAmount); // @dev use identical calldata structure as Mantis
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Ambient) {
            swap.data = swap.data.newAmbient(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Native) {
            revert("InputScalingHelper: Can not scale Native swap");
        } else if (DexIndex(functionSelectorIndex) == DexIndex.LighterV2) {
            swap.data = swap.data.newLighterV2(oldAmount, newAmount);
        } else if (DexIndex(functionSelectorIndex) == DexIndex.Bebop) {
            revert("InputScalingHelper: Can not scale Bebop swap");
        } else {
            revert("InputScaleHelper: Dex type not supported");
        }
        return swap;
    }

    function _flagsChecked(uint256 number, uint256 flag) internal pure returns (bool) {
        return number & flag != 0;
    }
}

File 25 of 27 : ScalingDataL2Lib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IExecutorHelper} from "../interfaces/IExecutorHelper.sol";
import {DexScaler} from "./DexScaler.sol";

library ScalingDataL2Lib {
    using DexScaler for bytes;

    function newUniSwap(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleUniSwap(oldAmount, newAmount);
    }

    function newStableSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleStableSwap(oldAmount, newAmount);
    }

    function newCurveSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleCurveSwap(oldAmount, newAmount);
    }

    function newKyberDMM(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleUniSwap(oldAmount, newAmount);
    }

    function newUniswapV3KSElastic(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleUniswapV3KSElastic(oldAmount, newAmount);
    }

    function newBalancerV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleBalancerV2(oldAmount, newAmount);
    }

    function newDODO(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleDODO(oldAmount, newAmount);
    }

    function newVelodrome(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleUniSwap(oldAmount, newAmount);
    }

    function newGMX(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleGMX(oldAmount, newAmount);
    }

    function newSynthetix(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleSynthetix(oldAmount, newAmount);
    }

    function newCamelot(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleUniSwap(oldAmount, newAmount);
    }

    function newPlatypus(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scalePlatypus(oldAmount, newAmount);
    }

    function newWrappedstETHSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleWrappedstETH(oldAmount, newAmount);
    }

    function newPSM(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scalePSM(oldAmount, newAmount);
    }

    function newFrax(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleUniSwap(oldAmount, newAmount);
    }

    function newStETHSwap(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleStETH(oldAmount, newAmount);
    }

    function newMaverick(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleMaverick(oldAmount, newAmount);
    }

    function newSyncSwap(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleSyncSwap(oldAmount, newAmount);
    }

    function newAlgebraV1(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleAlgebraV1(oldAmount, newAmount);
    }

    function newBalancerBatch(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleBalancerBatch(oldAmount, newAmount);
    }

    function newMantis(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleMantis(oldAmount, newAmount);
    }

    function newIziSwap(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleIziSwap(oldAmount, newAmount);
    }

    function newTraderJoeV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleTraderJoeV2(oldAmount, newAmount);
    }

    function newLevelFiV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleLevelFiV2(oldAmount, newAmount);
    }

    function newGMXGLP(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleGMXGLP(oldAmount, newAmount);
    }

    function newVooi(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleVooi(oldAmount, newAmount);
    }

    function newVelocoreV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleVelocoreV2(oldAmount, newAmount);
    }

    function newKokonut(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleKokonut(oldAmount, newAmount);
    }

    function newBalancerV1(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleBalancerV1(oldAmount, newAmount);
    }

    function newArbswapStable(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleArbswapStable(oldAmount, newAmount);
    }

    function newBancorV2(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleBancorV2(oldAmount, newAmount);
    }

    function newAmbient(bytes memory data, uint256 oldAmount, uint256 newAmount) internal pure returns (bytes memory) {
        return data.scaleAmbient(oldAmount, newAmount);
    }

    function newLighterV2(
        bytes memory data,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        return data.scaleLighterV2(oldAmount, newAmount);
    }
}

File 26 of 27 : I1inchAggregationRouterV5.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

interface I1inchAggregationRouterV5 {
    struct SwapDescription {
        IERC20 srcToken;
        IERC20 dstToken;
        address payable srcReceiver;
        address payable dstReceiver;
        uint256 amount;
        uint256 minReturnAmount;
        uint256 flags;
    }

    function uniswapV3SwapTo(
        address payable recipient,
        uint256 amount,
        uint256 minReturn,
        uint256[] calldata pools
    ) external payable returns (uint256 returnAmount);

    function swap(
        address executor,
        SwapDescription calldata desc,
        bytes calldata permit,
        bytes calldata data
    ) external payable returns (uint256 returnAmount, uint256 spentAmount);

    function unoswapTo(
        address payable recipient,
        address srcToken,
        uint256 amount,
        uint256 minReturn,
        uint256[] calldata pools
    ) external payable returns (uint256 returnAmount);
}

File 27 of 27 : OneInchAggregationRouterHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./I1inchAggregationRouterV5.sol";
import "../../../core/libraries/Errors.sol";

abstract contract OneInchAggregationRouterHelper {
    function _rescaleMinAmount(
        uint256 minAmount,
        uint256 oldAmount,
        uint256 newAmount
    ) internal pure returns (uint256) {
        return (minAmount * newAmount) / oldAmount;
    }

    function _get1inchScaledInputData(
        bytes calldata rawCallData,
        uint256 newAmount
    ) internal pure returns (bytes memory) {
        bytes4 selector = bytes4(rawCallData[:4]);
        bytes memory args = rawCallData[4:];

        if (selector == I1inchAggregationRouterV5.uniswapV3SwapTo.selector) {
            (address payable recipient, uint256 amount, uint256 minReturn, uint256[] memory pools) = abi.decode(
                args,
                (address, uint256, uint256, uint256[])
            );

            amount = newAmount;
            return abi.encodeWithSelector(selector, recipient, amount, minReturn, pools);
        }

        if (selector == I1inchAggregationRouterV5.swap.selector) {
            (
                address executor,
                I1inchAggregationRouterV5.SwapDescription memory desc,
                bytes memory permit,
                bytes memory data
            ) = abi.decode(args, (address, I1inchAggregationRouterV5.SwapDescription, bytes, bytes));

            desc.amount = newAmount;
            return abi.encodeWithSelector(selector, executor, desc, permit, data);
        }

        if (selector == I1inchAggregationRouterV5.unoswapTo.selector) {
            (
                address payable recipient,
                address srcToken,
                uint256 amount,
                uint256 minReturn,
                uint256[] memory pools
            ) = abi.decode(args, (address, address, uint256, uint256, uint256[]));

            amount = newAmount;
            return abi.encodeWithSelector(selector, recipient, srcToken, amount, minReturn, pools);
        }

        revert Errors.UnsupportedSelector(2, selector);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "viaIR": true,
  "evmVersion": "shanghai",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"aggregatorType","type":"uint256"},{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"UnsupportedSelector","type":"error"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"enum SwapType","name":"swapType","type":"uint8"},{"internalType":"address","name":"extRouter","type":"address"},{"internalType":"bytes","name":"extCalldata","type":"bytes"},{"internalType":"bool","name":"needScale","type":"bool"}],"internalType":"struct SwapData","name":"data","type":"tuple"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608080604052346100175761582d90816200001c8239f35b5f80fdfe608060405260048036101561001c575b50361561001a575f80fd5b005b5f3560e01c632bdb823c0361000f577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9060608236011261025d5780359173ffffffffffffffffffffffffffffffffffffffff83169283810361025d57602435906044359067ffffffffffffffff821161025d57608082860194833603011261025d576100bf906100ba60248401916100b4836102a0565b906104ef565b6102a0565b926064820135801515810361025d5715610261578035918583101561025d57839160446100ed9201906102c1565b9260018103610217575091610101926111e5565b935b610210575b6040519261011584610405565b602984527f416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c60208501527f7565206661696c65640000000000000000000000000000000000000000000000604085015281471061018c57505f848192602061001a9751920190855af16101866107b3565b916115ac565b6084906020604051917f08c379a0000000000000000000000000000000000000000000000000000000008352820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152fd5b505f610108565b9091506002036102315761022c918391610965565b610101565b6001857f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b5f80fd5b6102729060446102799301906102c1565b36916104b9565b93610103565b359073ffffffffffffffffffffffffffffffffffffffff8216820361025d57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361025d5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561025d570180359067ffffffffffffffff821161025d5760200191813603831361025d57565b60e0810190811067ffffffffffffffff82111761032e57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610160810190811067ffffffffffffffff82111761032e57604052565b60a0810190811067ffffffffffffffff82111761032e57604052565b60c0810190811067ffffffffffffffff82111761032e57604052565b6040810190811067ffffffffffffffff82111761032e57604052565b6080810190811067ffffffffffffffff82111761032e57604052565b610100810190811067ffffffffffffffff82111761032e57604052565b6060810190811067ffffffffffffffff82111761032e57604052565b610120810190811067ffffffffffffffff82111761032e57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761032e57604052565b67ffffffffffffffff811161032e57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926104c58261047f565b916104d3604051938461043e565b82948184528183011161025d578281602093845f960137010152565b9073ffffffffffffffffffffffffffffffffffffffff918281169081156107ad576040918251809581957fdd62ed3e0000000000000000000000000000000000000000000000000000000083523060048401521691826024830152602096879160449788915afa80156107a3575f9061076a575b6b7fffffffffffffffffffffff91501061057f575b5050505050565b8251905f808784017f095ea7b3000000000000000000000000000000000000000000000000000000009485825284602482015282898201528881526105c3816103cc565b519082875af16105d16107b3565b81610732575b50156106d657915f929183809386519089820193845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88820152878152610623816103cc565b51925af161062f6107b3565b8161069e575b5015610642578080610578565b606492917f5361666520417070726f766500000000000000000000000000000000000000009151927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b809150518481159182156106b7575b505090505f610635565b838092935001031261025d57836106ce91016107e2565b80845f6106ad565b6064867f5361666520417070726f76650000000000000000000000000000000000000000878751927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b8091505187811591821561074b575b505090505f6105d7565b838092935001031261025d578661076291016107e2565b80875f610741565b508581813d831161079c575b610780818361043e565b8101031261025d576b7fffffffffffffffffffffff9051610563565b503d610776565b84513d5f823e3d90fd5b50505050565b3d156107dd573d906107c48261047f565b916107d2604051938461043e565b82523d5f602084013e565b606090565b5190811515820361025d57565b519073ffffffffffffffffffffffffffffffffffffffff8216820361025d57565b67ffffffffffffffff811161032e5760051b60200190565b9080601f8301121561025d5781519060209161084381610810565b93610851604051958661043e565b81855260208086019260051b82010192831161025d57602001905b82821061087a575050505090565b8151815290830190830161086c565b9081518082526020808093019301915f5b8281106108a8575050505090565b83518552938101939281019260010161089a565b5f5b8381106108cd5750505f910152565b81810151838201526020016108be565b81601f8201121561025d5780516108f38161047f565b92610901604051948561043e565b8184526020828401011161025d5761091f91602080850191016108bc565b90565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209361095e815180928187528780880191016108bc565b0116010190565b91908060041161025d576109a0907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc369101600485016104b9565b7fbc80f1a8000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084351614610e08577f12aa3caf000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084351614610bcf577ff78dc253000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084351614610ad9576044837fffffffff00000000000000000000000000000000000000000000000000000000604051917fa7dd6a950000000000000000000000000000000000000000000000000000000083526002600484015235166024820152fd5b90918151820160a08382031261025d57610af5602084016107ef565b93610b02604085016107ef565b9060808501519060a08601519667ffffffffffffffff881161025d57610b5761091f9760207fffffffff000000000000000000000000000000000000000000000000000000009a81610ba39901920101610828565b9373ffffffffffffffffffffffffffffffffffffffff80926040519a8b99351660208a01521660248801521660448601526064850152608484015260a060a484015260c4830190610889565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810183528261043e565b909181518201928260208501940390610140821261025d5760e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610c16602087016107ef565b93011261025d5760405194610c2a86610312565b610c36604086016107ef565b8652610c44606086016107ef565b6020870152610c55608086016107ef565b6040870152610c6660a086016107ef565b606087015260c0850151608087015260e085015160a087015261010085015160c08701526101208501519067ffffffffffffffff9182811161025d57816020610cb1928901016108dd565b9061014087015192831161025d577fffffffff000000000000000000000000000000000000000000000000000000009773ffffffffffffffffffffffffffffffffffffffff610ba396610d1160c0946020610dd79861091f9d01016108dd565b9660808401526040519a8b99351660208a015216602488015273ffffffffffffffffffffffffffffffffffffffff815116604488015273ffffffffffffffffffffffffffffffffffffffff602082015116606488015273ffffffffffffffffffffffffffffffffffffffff604082015116608488015273ffffffffffffffffffffffffffffffffffffffff60608201511660a4880152608081015160c488015260a081015160e48801520151610104860152610140610124860152610164850190610922565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc84830301610144850152610922565b91825183019260808185031261025d57610e24602082016107ef565b606082015160808301519467ffffffffffffffff861161025d5773ffffffffffffffffffffffffffffffffffffffff610e8c610ba395602061091f99817fffffffff000000000000000000000000000000000000000000000000000000009c01920101610828565b9360405198899735166020880152166024860152604485015260648401526080608484015260a4830190610889565b9080601f8301121561025d576020908235610ed581610810565b93610ee3604051958661043e565b81855260208086019260051b82010192831161025d57602001905b828210610f0c575050505090565b838091610f188461027f565b815201910190610efe565b9080601f8301121561025d576020908235610f3d81610810565b93610f4b604051958661043e565b81855260208086019260051b82010192831161025d57602001905b828210610f74575050505090565b81358152908301908301610f66565b9080601f8301121561025d5781602061091f933591016104b9565b91906101608382031261025d5760405190610fb88261035b565b8193610fc38161027f565b8352610fd16020820161027f565b602084015267ffffffffffffffff91604082013583811161025d5781610ff8918401610ebb565b6040850152606082013583811161025d5781611015918401610f23565b6060850152608082013583811161025d5781611032918401610ebb565b608085015260a082013583811161025d578161104f918401610f23565b60a085015261106060c0830161027f565b60c085015260e082013560e085015261010080830135908501526101208083013590850152610140928383013590811161025d5761109e9201610f83565b910152565b9081518082526020808093019301915f5b8281106110c2575050505090565b835173ffffffffffffffffffffffffffffffffffffffff16855293810193928101926001016110b4565b9081518082526020808093019301915f5b82811061110b575050505090565b8351855293810193928101926001016110fd565b9061091f91610160916111a661119461118261117073ffffffffffffffffffffffffffffffffffffffff968787511686528760208801511660208701526040870151908060408801528601906110a3565b606086015185820360608701526110ec565b608085015184820360808601526110a3565b60a084015183820360a08501526110ec565b9260c08301511660c082015260e082015160e0820152610100808301519082015261012080830151908201526101408092015191818403910152610922565b909160049280841161025d5782357fffffffff000000000000000000000000000000000000000000000000000000001691848401917fe21fd0e90000000000000000000000000000000000000000000000000000000084036113dc5784017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc92602084878403011261025d57359467ffffffffffffffff9586811161025d5760a0910193848303011261025d576040519061129f82610378565b6112aa87850161027f565b82526112b86024850161027f565b9660208301978852604485013587811161025d5782826112da92880101610f83565b60408401908152606486013588811161025d5783836112fb92890101610f9e565b9360608101948552608487013598891161025d5761134a61132c6113cb956113979561091f9c610ba39b0101610f83565b966080830197885286519084516020610120840151161515926118d5565b83528552604051998a9860208a0152602060248a015273ffffffffffffffffffffffffffffffffffffffff8092511660448a0152511660648801525160a0608488015260e4870190610922565b9151917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc92838783030160a488015261111f565b9151908483030160c4850152610922565b909391907f8af033fb0000000000000000000000000000000000000000000000000000000084036115295782019060807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc848403011261025d57359473ffffffffffffffffffffffffffffffffffffffff861680960361025d5767ffffffffffffffff90602484013582811161025d57838261147a92870101610f9e565b91604485013581811161025d57848361149592880101610f83565b96606486013591821161025d5761091f976114c06114e99661151a956114c695610ba39a0101610f83565b946116ce565b9390604051988997602089015260248801526080604488015260a487019061111f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc9384878303016064880152610922565b91848303016084850152610922565b6084866020604051917f08c379a00000000000000000000000000000000000000000000000000000000083528201526024808201527f496e7075745363616c696e6748656c7065723a20496e76616c69642073656c6560448201527f63746f72000000000000000000000000000000000000000000000000000000006064820152fd5b9192901561162757508151156115c0575090565b3b156115c95790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b82519091501561163a5750805190602001fd5b611678906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352602060048401526024830190610922565b0390fd5b604051906116898261035b565b815f81525f602082015261014060609182604082015282808201528260808201528260a08201525f60c08201525f60e08201525f6101008201525f6101208201520152565b909291926116da61167c565b5060e0820151918483146118ce5784836116f392614d71565b91815191602092810191838301848385031261025d57848301519267ffffffffffffffff9384811161025d5760a091018095031261025d576040519761173889610378565b8585015184811161025d57828761175192880101614dec565b8952604085015184811161025d57828761176d92880101610828565b93868a01948552606086015181811161025d57838861178e92890101614e55565b9260408b0193845260808701519660608c0197885260a081015192831161025d576117bb920188016108dd565b9260808a019384528951515f5b81811061189b57505061186b94926117eb8593611854936118979a999751614fb4565b835261184361180f6040519c898e9a8b01525160a060408b015260e08a01906110a3565b9451947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc095868a83030160608b01526110ec565b905184888303016080890152614ed5565b925160a086015251908483030160c0850152610922565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810185528461043e565b9190565b806118bc846118b7876118b16001968d51614d5d565b51614ce6565b614d26565b6118c7828a51614d5d565b52016117c8565b9350919050565b939290936118e161167c565b5060e081015191838314614cde57614baf5782826118fe92614d71565b91845194602081878101031261025d5760208101519567ffffffffffffffff871161025d5760c0878301828401031261025d576040519661193e88610394565b6020818401015167ffffffffffffffff811161025d57602083850101603f828487010101121561025d576020818386010101519061197b82610810565b91611989604051938461043e565b808352602083019160208688010160408360051b83888b010101011161025d576040818689010101925b60408360051b83888b010101018410614a69575050505088526119da6040828501016107ef565b60208901526119ed6060828501016107ef565b6040890152611a006080828501016107ef565b606089015282810160a081015160808a015260c001519067ffffffffffffffff821161025d578360208793611a4193828997611a4c990101930101016108dd565b8060a08a0152614fb4565b60a0860152845151905f5b828110611be75750505050604051926020808501528381519160c06040830152825180610100840152610120906020828501928260051b8601019501915f905b828210611b1f57505050506118979260a082602061186b94015173ffffffffffffffffffffffffffffffffffffffff809116606087015280604083015116608087015260608201511682860152608081015160c086015201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08483030160e0850152610922565b9193947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0908792949703018252855190815180825260208201906020808260051b8501019401925f5b828110611b8a5750505050506020806001929701920192018894939192611a97565b9091929394602080827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086600195030188528851908280611bd48451604085526040850190610922565b9301519101529701950193929101611b68565b611bf2818851614d5d565b51805115614a3c5760200151907fffffffff000000000000000000000000000000000000000000000000000000006020830151167f593611990000000000000000000000000000000000000000000000000000000081145f14611c68575081611c5f8487600195516156ce565b90525b01611a57565b7fa8d2cb11000000000000000000000000000000000000000000000000000000008103611e4b575081516101208180518101031261025d57604051908161012081011067ffffffffffffffff6101208401111761032e57866118b786611d61936101208601604052611cdc602082016107ef565b8652611cea604082016107ef565b6020870152611cfb606082016107ef565b6040870152611d0c608082016153d8565b6060870152611d1d60a082016153d8565b6080870152611d5661012060c0830151928360a08a015260e081015160c08a0152611d4b61010082016107ef565b60e08a0152016107e2565b610100870152614ce6565b60a08201526101006040519173ffffffffffffffffffffffffffffffffffffffff815116602084015273ffffffffffffffffffffffffffffffffffffffff602082015116604084015273ffffffffffffffffffffffffffffffffffffffff6040820151166060840152606081015160ff809116608085015260808201511660a084015260a081015160c084015260c081015160e084015273ffffffffffffffffffffffffffffffffffffffff60e0820151168284015201511515610120820152610120815261014081019281841067ffffffffffffffff85111761032e5760019360405252611c62565b7fd90ce491000000000000000000000000000000000000000000000000000000008103611e89575081611e82848760019551615535565b9052611c62565b7fa3722546000000000000000000000000000000000000000000000000000000008103611ec0575081611e828487600195516156ce565b7f63407a49000000000000000000000000000000000000000000000000000000008103611fff5750815160e08180518101031261025d57600192611f82876118b78760405195611f0f87610312565b611f1b602082016107ef565b8752611f29604082016107ef565b6020880152611f3a606082016107ef565b6040880152611f4b608082016107ef565b6060880152611f7860e060a0830151928360808b0152611f6d60c082016107ef565b60a08b0152016107e2565b60c0880152614ce6565b608083015260c06040519273ffffffffffffffffffffffffffffffffffffffff808251166020860152806020830151166040860152806040830151166060860152806060830151166080860152608082015160a086015260a082015116828501520151151560e083015260e08252611ff9826103e8565b52611c62565b7fca6182da0000000000000000000000000000000000000000000000000000000081036120aa5760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65205246512073776170000000000000000000000000000000000000000000006064820152fd5b7f8cc7a56b0000000000000000000000000000000000000000000000000000000081036121995750815160a08180518101031261025d576001926040516120f081610378565b6120fc602084016107ef565b8152604083015160208201908152612116606085016107ef565b936040830194855260a061212c608083016107ef565b916060850192835201519261214c8b6118b78b6080850197808952614ce6565b84526040519573ffffffffffffffffffffffffffffffffffffffff938480935116602089015251604088015251166060860152511660808401525160a083015260a08252611ff982610394565b7f0ca8ebf10000000000000000000000000000000000000000000000000000000081036122595750815160608180518101031261025d57600192604051916121e083610405565b6121ec602082016107ef565b835260408101519061221c896118b78961220f606060208a0196888852016107e2565b9560408901968752614ce6565b815273ffffffffffffffffffffffffffffffffffffffff6040519451166020850152516040840152511515606083015260608252611ff9826103cc565b7feeb543140000000000000000000000000000000000000000000000000000000081036122bc575081519160208380518101031261025d576122a5866118b78660206001970151614ce6565b9060405191602083015260208252611ff9826103b0565b7f7b797563000000000000000000000000000000000000000000000000000000008103612416575081516101008180518101031261025d57600192612391876118b7876040519561230c876103e8565b612318602082016107ef565b8752612326604082016107ef565b6020880152612337606082016107ef565b6040880152612348608082016107ef565b606088015261238761010060a0830151928360808b015261236b60c082016107ef565b60a08b015261237c60e082016107e2565b60c08b0152016107e2565b60e0880152614ce6565b608083015260e06040519273ffffffffffffffffffffffffffffffffffffffff808251166020860152806020830151166040860152806040830151166060860152806060830151166080860152608082015160a086015260a08201511660c085015260c0810151151582850152015115156101008301526101008252611ff982610421565b7f55fad2fb00000000000000000000000000000000000000000000000000000000810361244d575081611e828487600195516156ce565b7f3b284cfe00000000000000000000000000000000000000000000000000000000810361251157508151918251830160a08482031261025d57600193602080612498930191016153e6565b90606082016124ac886118b7888451614ce6565b90526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015260608101516060860152015116910152565b60a08252611ff982610394565b7f74836acb0000000000000000000000000000000000000000000000000000000081036126375750815160e08180518101031261025d576001926040519161255883610312565b612564602082016107ef565b8352612572604082016107ef565b6020840152612583606082016107ef565b6040840152608081015160608401526125c8886118b7886125bb60e060a0870151968760808b015260c081015160a08b0152016107e2565b9460c08801958652614ce6565b608084015260a06040519373ffffffffffffffffffffffffffffffffffffffff808251166020870152806020830151166040870152604082015116606086015260608101516080860152608081015182860152015160c084015251151560e083015260e08252611ff9826103e8565b7f800023a10000000000000000000000000000000000000000000000000000000081036126e25760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f6520486173666c6f7720737761700000000000000000000000000000000000006064820152fd5b7f8df4a16b000000000000000000000000000000000000000000000000000000008103612719575081611e828487600195516156ce565b7fd6984a6d0000000000000000000000000000000000000000000000000000000081036127c45760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65204b796265724c4f20737761700000000000000000000000000000000000006064820152fd5b7f8f07985400000000000000000000000000000000000000000000000000000000810361280f57508151918251830160a08482031261025d57600193602080612498930191016153e6565b7fa9b3e398000000000000000000000000000000000000000000000000000000008103612846575081611e828487600195516156ce565b7f92749fe10000000000000000000000000000000000000000000000000000000081036128fc57508151918251830160a08482031261025d576001936020806128919301910161565b565b90608082016128a5886118b7888451614ce6565b90526125046040519260208401906080809173ffffffffffffffffffffffffffffffffffffffff80825116855280602083015116602086015280604083015116604086015260608201511660608501520151910152565b7f27c0cd18000000000000000000000000000000000000000000000000000000008103612a075750815160c08180518101031261025d5760019260405161294281610394565b61294e602084016107ef565b815261295c604084016107ef565b9260208201938452612970606082016107ef565b9360408301948552612984608083016107ef565b6060840190815260a0830151936129b28c6118b78c60c060808601988a8a5201519860a08601998a52614ce6565b84526040519673ffffffffffffffffffffffffffffffffffffffff8094818094511660208b01525116604089015251166060870152511660808501525160a08401525160c083015260c08252611ff982610312565b7fe756cac1000000000000000000000000000000000000000000000000000000008103612b815750815191825183019060208483031261025d57602084015167ffffffffffffffff811161025d5760a081860184031261025d57604051612a6d81610378565b602082870101519167ffffffffffffffff831161025d57600196612aa1611ff994602080612b2099019185850101016108dd565b8352612ab16040838301016107ef565b916020840192835260a0612ac96060838501016107ef565b9160408601928352612adf6080828601016107ef565b936060870194855201015191612b008d6118b78d6080890196808852614ce6565b83526040519788956020808801525160a0604088015260e0870190610922565b935173ffffffffffffffffffffffffffffffffffffffff9283809216606088015251166080860152511660a08401525160c0830152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810184528361043e565b7f48d31802000000000000000000000000000000000000000000000000000000008103612cb15750815160e08180518101031261025d57600192612c3c876118b78760405195612bd087610312565b612bdc602082016107ef565b8752612bea604082016107ef565b6020880152612bfb606082016107ef565b6040880152612c0c608082016107ef565b606088015260e060a0820151918260808a0152612c2b60c082016107ef565b60a08a0152015160c0880152614ce6565b608083015260c06040519273ffffffffffffffffffffffffffffffffffffffff808251166020860152806020830151166040860152806040830151166060860152806060830151166080860152608082015160a086015260a08201511682850152015160e083015260e08252611ff9826103e8565b7f04cca9f7000000000000000000000000000000000000000000000000000000008103612f405750908051908151820160208382031261025d57602083015167ffffffffffffffff811161025d5760a081850183031261025d5760405193612d1885610378565b612d266020838301016107ef565b85526040828201015167ffffffffffffffff811161025d5760208401603f828585010101121561025d57602081848401010151612d6281610810565b91612d70604051938461043e565b81835260208301906020870160408460051b838989010101011161025d576040818787010101915b60408460051b838989010101018310612f30575050505060208601526060828201015167ffffffffffffffff811161025d57612dde906020808601918585010101614dec565b6040860152608082820101519267ffffffffffffffff841161025d5760a08a936118b793612e1a612e2d976020808e9701918585010101614e55565b60608a0152010151806080880152614ce6565b60808301526040519160208084015260e0830173ffffffffffffffffffffffffffffffffffffffff825116604085015260208201519060a060608601528151809152602061010086019201905f905b808210612f185750505083826080612ee4611ff994612ecf604060019b9a99980151917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0928388830301868901526110a3565b906060850151908683030160a0870152614ed5565b91015160c0830152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810184528361043e565b90919260208060019286518152019401920190612e7c565b8251815260209283019201612d98565b7faa293da2000000000000000000000000000000000000000000000000000000008103612f77575081611e82848760019551615443565b7f517e7ca1000000000000000000000000000000000000000000000000000000008103612fae575081611e82848760019551615443565b7f1b96cfd40000000000000000000000000000000000000000000000000000000081036130cd575081519160c08380518101031261025d5760405190612ff382610394565b612fff602085016107ef565b825261300d604085016107ef565b602083015261301e606085016107ef565b604083015261302f608085016107ef565b606083015260c060a08501519485608085015201518060020b810361025d57613065886118b78860019860a08801958652614ce6565b608084015260806040519373ffffffffffffffffffffffffffffffffffffffff80825116602087015280602083015116604087015280604083015116606087015260608201511682860152015160a08401525160020b60c083015260c08252611ff982610312565b7f5987cf43000000000000000000000000000000000000000000000000000000008103613104575081611e82848760019551615443565b7fc43025bd00000000000000000000000000000000000000000000000000000000810361320157508151918251830160a08482031261025d5760019360208061314f9301910161565b565b906080820180517f80000000000000000000000000000000000000000000000000000000000000006131a78a6118b78a7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614ce6565b91161790526125046040519260208401906080809173ffffffffffffffffffffffffffffffffffffffff80825116855280602083015116602086015280604083015116604086015260608201511660608501520151910152565b7f63d71df3000000000000000000000000000000000000000000000000000000008103613238575081611e82848760019551615535565b7fe7e1b5cb0000000000000000000000000000000000000000000000000000000081036133445750815160c08180518101031261025d5760019260405161327e81610394565b61328a602084016107ef565b8152613298604084016107ef565b90602081019182526132ac606085016107ef565b936040820194855260808101519160608101908382526132ef8c6118b78c6132e260c060a08901519860808801998a52016107ef565b9760a08601988952614ce6565b82526040519673ffffffffffffffffffffffffffffffffffffffff8096818094511660208b015251166040890152511660608701525160808601525160a0850152511660c083015260c08252611ff982610312565b7f3ac19910000000000000000000000000000000000000000000000000000000008103613494575081516101008180518101031261025d5760019261340f876118b78760405195613394876103e8565b6133a0602082016107ef565b87526133ae604082016107ef565b60208801526133bf606082016107ef565b60408801526133d0608082016107ef565b60608801526133e160a082016107ef565b60808801526133f260c082016107ef565b60a088015261238761010060e0830151928360c08b0152016107ef565b60c083015273ffffffffffffffffffffffffffffffffffffffff60e0604051938281511660208601528260208201511660408601528260408201511660608601528260608201511660808601528260808201511660a08601528260a08201511660c086015260c0810151828601520151166101008301526101008252611ff982610421565b7f37e96a470000000000000000000000000000000000000000000000000000000081036135b25750815160e08180518101031261025d576001926040516134da81610312565b6134e6602084016107ef565b81526134f4604084016107ef565b9060208101918252613508606085016107ef565b936040820194855260808101516060830190815260a0820151906080840191825260c0830151936135578d6118b78d61354a60e060a08701998b8b52016107ef565b9860c08601998a52614ce6565b84526040519773ffffffffffffffffffffffffffffffffffffffff8097818094511660208c0152511660408a0152511660608801525160808701525160a08601525160c0850152511660e083015260e08252611ff9826103e8565b7f4a8ac7610000000000000000000000000000000000000000000000000000000081036136e55750815160e08180518101031261025d57600192604051916135f983610312565b613605602082016107ef565b83526040810151906020840190828252613621606082016107ef565b9160408601928352613635608083016107ef565b956060810196875261364960a084016107ef565b90608081019182526136858d6118b78d61367860e061366a60c08b016107ef565b9960a088019a8b52016107e2565b9960c086019a8b52614ce6565b83526040519773ffffffffffffffffffffffffffffffffffffffff80968195828095511660208d01525160408c0152511660608a015251166080880152511660a0860152511660c084015251151560e083015260e08252611ff9826103e8565b7fc8e128e40000000000000000000000000000000000000000000000000000000081036137c35750815160808180518101031261025d576001926040519161372c836103cc565b613738602082016107ef565b8352613746604082016107ef565b906020840191825260608101519061377c8a6118b78a61376f608060408b0196888852016107ef565b9560608a01968752614ce6565b81526040519473ffffffffffffffffffffffffffffffffffffffff9384809251166020880152511660408601525160608501525116608083015260808252611ff982610378565b7ffac08e6f0000000000000000000000000000000000000000000000000000000081036137fa575081611e82848760019551615443565b7fe445a7ec000000000000000000000000000000000000000000000000000000008103613831575081611e82848760019551615443565b7f944432e00000000000000000000000000000000000000000000000000000000081036138e657508151918251830160a08482031261025d5760019360208061387c930191016154dc565b9060208201613890886118b7888451614ce6565b90526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff918281511685526020810151602086015260408101516040860152826060820151166060860152015116910152565b7f0e00deaa0000000000000000000000000000000000000000000000000000000081036139c35750815160808180518101031261025d576001926040519161392d836103cc565b613939602082016107ef565b8352613947604082016107ef565b60208401908152608061395c606084016107ef565b926040860193845201519161397c8a6118b78a6060890196808852614ce6565b83526040519473ffffffffffffffffffffffffffffffffffffffff9283809251166020880152511660408601525116606084015251608083015260808252611ff982610378565b7f67f2255d000000000000000000000000000000000000000000000000000000008103613a6e5760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65205377616170563220737761700000000000000000000000000000000000006064820152fd5b7f48bad50c000000000000000000000000000000000000000000000000000000008103613aa5575081611e82848760019551615443565b7fb1f7d82d000000000000000000000000000000000000000000000000000000008103613af057508151918251830160a08482031261025d5760019360208061387c930191016154dc565b7f68abdc71000000000000000000000000000000000000000000000000000000008103613c4d5750815191825183019060208483031261025d5760208401519367ffffffffffffffff851161025d57608085820184031261025d5760405194613b58866103cc565b613b666020828401016107ef565b8652604081830101519167ffffffffffffffff831161025d57600196613b9c611ff994602080613c139901918686010101614dec565b9260208201938452613bd58c6118b78c613bc860806060878a010151966040890199888b5201016107ef565b9460608701958652614ce6565b835260405196879460208087015273ffffffffffffffffffffffffffffffffffffffff809451166040870152516080606087015260c08601906110a3565b92516080850152511660a0830152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810184528361043e565b7f152dc1cf000000000000000000000000000000000000000000000000000000008103613c84575081611e82848760019551615443565b7f98923834000000000000000000000000000000000000000000000000000000008103613dd8575081519160c08380518101031261025d5760405190613cc982610394565b613cd5602085016107ef565b825260408401516fffffffffffffffffffffffffffffffff8116810361025d57613d5b886118b7886fffffffffffffffffffffffffffffffff85613d5060c060019c849960208d0152613d2a606082016107ef565b60408d0152613d3b608082016107ef565b60608d015260a081015160808d0152016153d8565b60a08a015216614ce6565b16602083015260ff60a06040519373ffffffffffffffffffffffffffffffffffffffff8082511660208701526fffffffffffffffffffffffffffffffff6020830151166040870152806040830151166060870152606082015116608086015260808101518286015201511660c083015260c08252611ff982610312565b7e3c5f89000000000000000000000000000000000000000000000000000000008103613e825760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65204e61746976652073776170000000000000000000000000000000000000006064820152fd5b7fddfb5cb6000000000000000000000000000000000000000000000000000000008103613fa95750815160c08180518101031261025d5760019260405191613ec983610394565b613ed5602082016107ef565b8352604081015160208401818152613eef606084016107e2565b9260408601938452613f03608082016107ef565b95606081019687526fffffffffffffffffffffffffffffffff613f508d6118b78d613f4360c0613f3560a08a016107ef565b9860808901998a52016107ef565b9860a08701998a52614ce6565b1683526040519673ffffffffffffffffffffffffffffffffffffffff958694858094511660208b01525160408a0152511515606089015251166080870152511660a0850152511660c083015260c08252611ff982610312565b7f3bbc6abf0000000000000000000000000000000000000000000000000000000081036140545760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65204265626f70207377617000000000000000000000000000000000000000006064820152fd5b7f180a5b7600000000000000000000000000000000000000000000000000000000810361411d57508151918251830160a08482031261025d5760019360208061409f9301910161532f565b90602082016fffffffffffffffffffffffffffffffff6140c4896118b7898551614ce6565b1690526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855260208101516020860152826040820151166040860152826060820151166060860152015116910152565b7f63123dbb000000000000000000000000000000000000000000000000000000008103614154575081611e82848760019551615194565b7ff9c357e00000000000000000000000000000000000000000000000000000000081036141f75750815160408180518101031261025d576001926040519161419b836103b0565b6fffffffffffffffffffffffffffffffff6141d5896118b7896141c86040602088015197888b52016107e2565b9560208901968752614ce6565b16809352604051926020840152511515604083015260408252611ff982610405565b7fd883ad9f0000000000000000000000000000000000000000000000000000000081036142a457508151918251830160408482031261025d5760019360208061424293019101615292565b906fffffffffffffffffffffffffffffffff614263886118b7888651614ce6565b16825261429760405192602084019073ffffffffffffffffffffffffffffffffffffffff6020809280518552015116910152565b60408252611ff982610405565b7f0343ecaf0000000000000000000000000000000000000000000000000000000081036142db575081611e828487600195516152bc565b7f020918a10000000000000000000000000000000000000000000000000000000081036143c057508151918251830160408482031261025d57600193602080614326930191016151dc565b90602082016fffffffffffffffffffffffffffffffff61434d896118b78984865116614ce6565b167f8000000000000000000000000000000000000000000000000000000000000000868351908060ff92831c145f146143b857905b1b161790526142976040519260208401906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b505f90614382565b7f95d02f7d0000000000000000000000000000000000000000000000000000000081036144a157508151918251830160408482031261025d5760019360208061440b93019101615292565b906fffffffffffffffffffffffffffffffff61442e886118b78884875116614ce6565b167f8000000000000000000000000000000000000000000000000000000000000000858451908060ff92831c145f1461449957905b1b1617825261429760405192602084019073ffffffffffffffffffffffffffffffffffffffff6020809280518552015116910152565b505f90614463565b7fc390adea00000000000000000000000000000000000000000000000000000000810361456b57508151918251830160808482031261025d576001936020806144ec9301910161538c565b90602082016fffffffffffffffffffffffffffffffff614511896118b7898551614ce6565b16905261455e6040519260208401906060908173ffffffffffffffffffffffffffffffffffffffff9182815116855260208101516020860152826040820151166040860152015116910152565b60808252611ff982610378565b7fc9989fac0000000000000000000000000000000000000000000000000000000081036145a2575081611e82848760019551615194565b7f5829bd520000000000000000000000000000000000000000000000000000000081036145d9575081611e82848760019551615194565b7f87ab3c27000000000000000000000000000000000000000000000000000000008103614610575081611e828487600195516150ef565b7fba176e5c00000000000000000000000000000000000000000000000000000000810361465b57508151918251830160808482031261025d576001936020806144ec9301910161538c565b7fe937b9a900000000000000000000000000000000000000000000000000000000810361476557508151918251830160a08482031261025d576001936020806146a69301910161532f565b90602082016fffffffffffffffffffffffffffffffff6146cd896118b78984865116614ce6565b167f8000000000000000000000000000000000000000000000000000000000000000868351908060ff92831c145f1461475d57905b1b161790526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855260208101516020860152826040820151166040860152826060820151166060860152015116910152565b505f90614702565b7f323b615300000000000000000000000000000000000000000000000000000000810361479c575081611e82848760019551615194565b7ff17912eb0000000000000000000000000000000000000000000000000000000081036147d3575081611e82848760019551615194565b7fcebf718d00000000000000000000000000000000000000000000000000000000810361480a575081611e828487600195516152bc565b7fa8e60da0000000000000000000000000000000000000000000000000000000008103614841575081611e8284876001955161520b565b7fd5c275ad000000000000000000000000000000000000000000000000000000008103614878575081611e8284876001955161520b565b7fac40622c00000000000000000000000000000000000000000000000000000000810361494c575081519160208380518101031261025d5760206001930151906fffffffffffffffffffffffffffffffff6148d9886118b788848716614ce6565b16848060ff94851c145f14614924577f8000000000000000000000000000000000000000000000000000000000000000905b604051941b1617602083015260208252611ff9826103b0565b507f80000000000000000000000000000000000000000000000000000000000000005f61490b565b7fe93d0ac7000000000000000000000000000000000000000000000000000000008103614983575081611e82848760019551615194565b7fd1019fd000000000000000000000000000000000000000000000000000000000036149b85781611e828487600195516150ef565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4167677265676174696f6e4578656375746f723a204465782074797065206e6f60448201527f7420737570706f727465640000000000000000000000000000000000000000006064820152fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b835167ffffffffffffffff811161025d576020888a0101605f82858a8d01010101121561025d5760408184898c010101015188614aa582610810565b92614ab3604051948561043e565b8284526020808501928d01018c8b0187018201600585901b016060011161025d578960608d8389838282878601010101945b8860051b9301010101018110614b085750505090825250602093840193016119b3565b80519267ffffffffffffffff841161025d5760407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08f8f968f8c889184010101019687910103011261025d5760405193614b61856103b0565b60608101519467ffffffffffffffff861161025d578f918f8f97606095889460808f95614b9b602096958b8880988d0101918401016108dd565b835201518382015281520195019496614ae5565b8282614bbe9296939496614d71565b91815191602092810191838301848385031261025d57848301519267ffffffffffffffff9384811161025d5760a091018095031261025d5760405197614c0389610378565b8585015184811161025d578287614c1c92880101614dec565b8952604085015184811161025d578287614c3892880101610828565b93868a01948552606086015181811161025d578388614c5992890101614e55565b9260408b0193845260808701519660608c0197885260a081015192831161025d57614c86920188016108dd565b9260808a019384528951515f5b818110614cb657505061186b94926117eb8593611854936118979a999751614fb4565b80614ccc846118b7876118b16001968d51614d5d565b614cd7828a51614d5d565b5201614c93565b509150509190565b81810292918115918404141715614cf957565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8115614d30570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b8051821015614a3c5760209160051b010190565b91614d7a61167c565b506101008301614d8f836118b7848451614ce6565b80825215614de2575b508060e0840152604083015151915f5b838110614db6575050505090565b60019060608601614ddb82614dd4866118b7896118b1858851614d5d565b9251614d5d565b5201614da8565b600190525f614d98565b9080601f8301121561025d57815190602091614e0781610810565b93614e15604051958661043e565b81855260208086019260051b82010192831161025d57602001905b828210614e3e575050505090565b838091614e4a846107ef565b815201910190614e30565b81601f8201121561025d57805191602091614e6f84610810565b93614e7d604051958661043e565b808552838086019160051b8301019280841161025d57848301915b848310614ea85750505050505090565b825167ffffffffffffffff811161025d578691614eca848480948901016108dd565b815201920191614e98565b90808251908181526020809101926020808460051b8301019501935f915b848310614f035750505050505090565b9091929394958480614f3f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086600196030187528a51610922565b9801930193019194939290614ef3565b15614f5657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f457863656564656420747970652072616e6765000000000000000000000000006044820152fd5b919082918251906020918281115f1461505c5750835160409485918101031261025d577fffffffffffffffffffffffffffffffff0000000000000000000000000000000084805196615005886103b0565b8481015188520151615040615037858901968388526118b76fffffffffffffffffffffffffffffffff96878616614ce6565b93841115614f4f565b1617825282519351908401525181830152815261091f81610405565b9091809394508114615070575b5050505090565b918480929382959601031261025d576150a7836150b0920151946118b76fffffffffffffffffffffffffffffffff94858816614ce6565b91821115614f4f565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000006040519316178183015281526150e6816103b0565b5f808080615069565b9160608380518101031261025d576fffffffffffffffffffffffffffffffff6151556040519361511e85610405565b61512a602087016107ef565b85526118b760408701519461514860606020890199888b52016107ef565b9560408801968752614ce6565b1683526040519273ffffffffffffffffffffffffffffffffffffffff809351166020850152516040840152511660608201526060815261091f816103cc565b919060208380518101031261025d576118b76151c59260206fffffffffffffffffffffffffffffffff950151614ce6565b166040519060208201526020815261091f816103b0565b919082604091031261025d576040516151f4816103b0565b6020808294615202816107ef565b84520151910152565b919091805181019060408183031261025d57615241615251916020806fffffffffffffffffffffffffffffffff950191016151dc565b936118b760208601948551614ce6565b1690526152856040519160208301906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b6040815261091f81610405565b919082604091031261025d576040516152aa816103b0565b602061109e81839580518552016107ef565b90815182019060408383031261025d576118b76152f36fffffffffffffffffffffffffffffffff946020806152fb96019101615292565b948551614ce6565b16815261528560405191602083019073ffffffffffffffffffffffffffffffffffffffff6020809280518552015116910152565b91908260a091031261025d5760405161534781610378565b608061109e818395615358816107ef565b855260208101516020860152615370604082016107ef565b6040860152615381606082016107ef565b6060860152016107ef565b919082608091031261025d576040516153a4816103cc565b606061109e8183956153b5816107ef565b8552602081015160208601526153cd604082016107ef565b6040860152016107ef565b519060ff8216820361025d57565b91908260a091031261025d576040516153fe81610378565b608061109e81839561540f816107ef565b855261541d602082016107ef565b602086015261542e604082016107ef565b604086015260608101516060860152016107ef565b9190918051810160a08282031261025d5761547791602080615467930191016153e6565b926118b760608501938451614ce6565b90526154cf6040519160208301906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015260608101516060860152015116910152565b60a0815261091f81610394565b91908260a091031261025d576040516154f481610378565b608061109e818395615505816107ef565b85526020810151602086015260408101516040860152615381606082016107ef565b519081600f0b820361025d57565b9190829182516101009485918101031261025d5760a08493604051958694859461555e866103e8565b61556a602085016107ef565b86526155f561557b604086016107ef565b92602088019384526118b7615592606088016107ef565b9360408a019485528960e06155eb6155ac60808c01615527565b99606084019a8b526155bf8d8d01615527565b9b608085019c8d5260c08101519d8e95019d8e5260c06155e08583016107e2565b9f019e8f52016107e2565b9c019b8c52614ce6565b85526040519873ffffffffffffffffffffffffffffffffffffffff92838092511660208c0152511660408a01525116606088015251600f0b608087015251600f0b60a08601525160c085015251151560e084015251151581830152815261091f81610421565b91908260a091031261025d5760405161567381610378565b6080808294615681816107ef565b845261568f602082016107ef565b60208501526156a0604082016107ef565b60408501526156b1606082016107ef565b60608501520151910152565b519063ffffffff8216820361025d57565b80919281516101009384918101031261025d57818060c092604051906156f3826103e8565b6156ff602084016107ef565b825261570d604084016107ef565b916020810192835261578d615724606086016107ef565b99604083019a8b526118b761573b608088016107ef565b94606085019586526157808c61577260e061576460a08d01519e8f9d60808c019e8f52016156bd565b9c60a08a019d8e52016156bd565b9c60c088019d8e52016156bd565b9960e086019a8b52614ce6565b84526040519873ffffffffffffffffffffffffffffffffffffffff8094818094511660208d0152511660408b015251166060890152511660808701525160a08601525163ffffffff928380921660c0870152511660e0850152511681830152815261091f8161042156fea2646970667358221220d0795bdc5bd2dd32e5c1d0a36090ad6cd21b3d392ef24a8e99c59565c715baa464736f6c63430008180033

Deployed Bytecode

0x608060405260048036101561001c575b50361561001a575f80fd5b005b5f3560e01c632bdb823c0361000f577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9060608236011261025d5780359173ffffffffffffffffffffffffffffffffffffffff83169283810361025d57602435906044359067ffffffffffffffff821161025d57608082860194833603011261025d576100bf906100ba60248401916100b4836102a0565b906104ef565b6102a0565b926064820135801515810361025d5715610261578035918583101561025d57839160446100ed9201906102c1565b9260018103610217575091610101926111e5565b935b610210575b6040519261011584610405565b602984527f416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c60208501527f7565206661696c65640000000000000000000000000000000000000000000000604085015281471061018c57505f848192602061001a9751920190855af16101866107b3565b916115ac565b6084906020604051917f08c379a0000000000000000000000000000000000000000000000000000000008352820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152fd5b505f610108565b9091506002036102315761022c918391610965565b610101565b6001857f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b5f80fd5b6102729060446102799301906102c1565b36916104b9565b93610103565b359073ffffffffffffffffffffffffffffffffffffffff8216820361025d57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361025d5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561025d570180359067ffffffffffffffff821161025d5760200191813603831361025d57565b60e0810190811067ffffffffffffffff82111761032e57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610160810190811067ffffffffffffffff82111761032e57604052565b60a0810190811067ffffffffffffffff82111761032e57604052565b60c0810190811067ffffffffffffffff82111761032e57604052565b6040810190811067ffffffffffffffff82111761032e57604052565b6080810190811067ffffffffffffffff82111761032e57604052565b610100810190811067ffffffffffffffff82111761032e57604052565b6060810190811067ffffffffffffffff82111761032e57604052565b610120810190811067ffffffffffffffff82111761032e57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761032e57604052565b67ffffffffffffffff811161032e57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926104c58261047f565b916104d3604051938461043e565b82948184528183011161025d578281602093845f960137010152565b9073ffffffffffffffffffffffffffffffffffffffff918281169081156107ad576040918251809581957fdd62ed3e0000000000000000000000000000000000000000000000000000000083523060048401521691826024830152602096879160449788915afa80156107a3575f9061076a575b6b7fffffffffffffffffffffff91501061057f575b5050505050565b8251905f808784017f095ea7b3000000000000000000000000000000000000000000000000000000009485825284602482015282898201528881526105c3816103cc565b519082875af16105d16107b3565b81610732575b50156106d657915f929183809386519089820193845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88820152878152610623816103cc565b51925af161062f6107b3565b8161069e575b5015610642578080610578565b606492917f5361666520417070726f766500000000000000000000000000000000000000009151927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b809150518481159182156106b7575b505090505f610635565b838092935001031261025d57836106ce91016107e2565b80845f6106ad565b6064867f5361666520417070726f76650000000000000000000000000000000000000000878751927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b8091505187811591821561074b575b505090505f6105d7565b838092935001031261025d578661076291016107e2565b80875f610741565b508581813d831161079c575b610780818361043e565b8101031261025d576b7fffffffffffffffffffffff9051610563565b503d610776565b84513d5f823e3d90fd5b50505050565b3d156107dd573d906107c48261047f565b916107d2604051938461043e565b82523d5f602084013e565b606090565b5190811515820361025d57565b519073ffffffffffffffffffffffffffffffffffffffff8216820361025d57565b67ffffffffffffffff811161032e5760051b60200190565b9080601f8301121561025d5781519060209161084381610810565b93610851604051958661043e565b81855260208086019260051b82010192831161025d57602001905b82821061087a575050505090565b8151815290830190830161086c565b9081518082526020808093019301915f5b8281106108a8575050505090565b83518552938101939281019260010161089a565b5f5b8381106108cd5750505f910152565b81810151838201526020016108be565b81601f8201121561025d5780516108f38161047f565b92610901604051948561043e565b8184526020828401011161025d5761091f91602080850191016108bc565b90565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209361095e815180928187528780880191016108bc565b0116010190565b91908060041161025d576109a0907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc369101600485016104b9565b7fbc80f1a8000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084351614610e08577f12aa3caf000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084351614610bcf577ff78dc253000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084351614610ad9576044837fffffffff00000000000000000000000000000000000000000000000000000000604051917fa7dd6a950000000000000000000000000000000000000000000000000000000083526002600484015235166024820152fd5b90918151820160a08382031261025d57610af5602084016107ef565b93610b02604085016107ef565b9060808501519060a08601519667ffffffffffffffff881161025d57610b5761091f9760207fffffffff000000000000000000000000000000000000000000000000000000009a81610ba39901920101610828565b9373ffffffffffffffffffffffffffffffffffffffff80926040519a8b99351660208a01521660248801521660448601526064850152608484015260a060a484015260c4830190610889565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810183528261043e565b909181518201928260208501940390610140821261025d5760e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610c16602087016107ef565b93011261025d5760405194610c2a86610312565b610c36604086016107ef565b8652610c44606086016107ef565b6020870152610c55608086016107ef565b6040870152610c6660a086016107ef565b606087015260c0850151608087015260e085015160a087015261010085015160c08701526101208501519067ffffffffffffffff9182811161025d57816020610cb1928901016108dd565b9061014087015192831161025d577fffffffff000000000000000000000000000000000000000000000000000000009773ffffffffffffffffffffffffffffffffffffffff610ba396610d1160c0946020610dd79861091f9d01016108dd565b9660808401526040519a8b99351660208a015216602488015273ffffffffffffffffffffffffffffffffffffffff815116604488015273ffffffffffffffffffffffffffffffffffffffff602082015116606488015273ffffffffffffffffffffffffffffffffffffffff604082015116608488015273ffffffffffffffffffffffffffffffffffffffff60608201511660a4880152608081015160c488015260a081015160e48801520151610104860152610140610124860152610164850190610922565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc84830301610144850152610922565b91825183019260808185031261025d57610e24602082016107ef565b606082015160808301519467ffffffffffffffff861161025d5773ffffffffffffffffffffffffffffffffffffffff610e8c610ba395602061091f99817fffffffff000000000000000000000000000000000000000000000000000000009c01920101610828565b9360405198899735166020880152166024860152604485015260648401526080608484015260a4830190610889565b9080601f8301121561025d576020908235610ed581610810565b93610ee3604051958661043e565b81855260208086019260051b82010192831161025d57602001905b828210610f0c575050505090565b838091610f188461027f565b815201910190610efe565b9080601f8301121561025d576020908235610f3d81610810565b93610f4b604051958661043e565b81855260208086019260051b82010192831161025d57602001905b828210610f74575050505090565b81358152908301908301610f66565b9080601f8301121561025d5781602061091f933591016104b9565b91906101608382031261025d5760405190610fb88261035b565b8193610fc38161027f565b8352610fd16020820161027f565b602084015267ffffffffffffffff91604082013583811161025d5781610ff8918401610ebb565b6040850152606082013583811161025d5781611015918401610f23565b6060850152608082013583811161025d5781611032918401610ebb565b608085015260a082013583811161025d578161104f918401610f23565b60a085015261106060c0830161027f565b60c085015260e082013560e085015261010080830135908501526101208083013590850152610140928383013590811161025d5761109e9201610f83565b910152565b9081518082526020808093019301915f5b8281106110c2575050505090565b835173ffffffffffffffffffffffffffffffffffffffff16855293810193928101926001016110b4565b9081518082526020808093019301915f5b82811061110b575050505090565b8351855293810193928101926001016110fd565b9061091f91610160916111a661119461118261117073ffffffffffffffffffffffffffffffffffffffff968787511686528760208801511660208701526040870151908060408801528601906110a3565b606086015185820360608701526110ec565b608085015184820360808601526110a3565b60a084015183820360a08501526110ec565b9260c08301511660c082015260e082015160e0820152610100808301519082015261012080830151908201526101408092015191818403910152610922565b909160049280841161025d5782357fffffffff000000000000000000000000000000000000000000000000000000001691848401917fe21fd0e90000000000000000000000000000000000000000000000000000000084036113dc5784017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc92602084878403011261025d57359467ffffffffffffffff9586811161025d5760a0910193848303011261025d576040519061129f82610378565b6112aa87850161027f565b82526112b86024850161027f565b9660208301978852604485013587811161025d5782826112da92880101610f83565b60408401908152606486013588811161025d5783836112fb92890101610f9e565b9360608101948552608487013598891161025d5761134a61132c6113cb956113979561091f9c610ba39b0101610f83565b966080830197885286519084516020610120840151161515926118d5565b83528552604051998a9860208a0152602060248a015273ffffffffffffffffffffffffffffffffffffffff8092511660448a0152511660648801525160a0608488015260e4870190610922565b9151917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc92838783030160a488015261111f565b9151908483030160c4850152610922565b909391907f8af033fb0000000000000000000000000000000000000000000000000000000084036115295782019060807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc848403011261025d57359473ffffffffffffffffffffffffffffffffffffffff861680960361025d5767ffffffffffffffff90602484013582811161025d57838261147a92870101610f9e565b91604485013581811161025d57848361149592880101610f83565b96606486013591821161025d5761091f976114c06114e99661151a956114c695610ba39a0101610f83565b946116ce565b9390604051988997602089015260248801526080604488015260a487019061111f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc9384878303016064880152610922565b91848303016084850152610922565b6084866020604051917f08c379a00000000000000000000000000000000000000000000000000000000083528201526024808201527f496e7075745363616c696e6748656c7065723a20496e76616c69642073656c6560448201527f63746f72000000000000000000000000000000000000000000000000000000006064820152fd5b9192901561162757508151156115c0575090565b3b156115c95790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b82519091501561163a5750805190602001fd5b611678906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352602060048401526024830190610922565b0390fd5b604051906116898261035b565b815f81525f602082015261014060609182604082015282808201528260808201528260a08201525f60c08201525f60e08201525f6101008201525f6101208201520152565b909291926116da61167c565b5060e0820151918483146118ce5784836116f392614d71565b91815191602092810191838301848385031261025d57848301519267ffffffffffffffff9384811161025d5760a091018095031261025d576040519761173889610378565b8585015184811161025d57828761175192880101614dec565b8952604085015184811161025d57828761176d92880101610828565b93868a01948552606086015181811161025d57838861178e92890101614e55565b9260408b0193845260808701519660608c0197885260a081015192831161025d576117bb920188016108dd565b9260808a019384528951515f5b81811061189b57505061186b94926117eb8593611854936118979a999751614fb4565b835261184361180f6040519c898e9a8b01525160a060408b015260e08a01906110a3565b9451947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc095868a83030160608b01526110ec565b905184888303016080890152614ed5565b925160a086015251908483030160c0850152610922565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810185528461043e565b9190565b806118bc846118b7876118b16001968d51614d5d565b51614ce6565b614d26565b6118c7828a51614d5d565b52016117c8565b9350919050565b939290936118e161167c565b5060e081015191838314614cde57614baf5782826118fe92614d71565b91845194602081878101031261025d5760208101519567ffffffffffffffff871161025d5760c0878301828401031261025d576040519661193e88610394565b6020818401015167ffffffffffffffff811161025d57602083850101603f828487010101121561025d576020818386010101519061197b82610810565b91611989604051938461043e565b808352602083019160208688010160408360051b83888b010101011161025d576040818689010101925b60408360051b83888b010101018410614a69575050505088526119da6040828501016107ef565b60208901526119ed6060828501016107ef565b6040890152611a006080828501016107ef565b606089015282810160a081015160808a015260c001519067ffffffffffffffff821161025d578360208793611a4193828997611a4c990101930101016108dd565b8060a08a0152614fb4565b60a0860152845151905f5b828110611be75750505050604051926020808501528381519160c06040830152825180610100840152610120906020828501928260051b8601019501915f905b828210611b1f57505050506118979260a082602061186b94015173ffffffffffffffffffffffffffffffffffffffff809116606087015280604083015116608087015260608201511682860152608081015160c086015201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08483030160e0850152610922565b9193947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0908792949703018252855190815180825260208201906020808260051b8501019401925f5b828110611b8a5750505050506020806001929701920192018894939192611a97565b9091929394602080827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086600195030188528851908280611bd48451604085526040850190610922565b9301519101529701950193929101611b68565b611bf2818851614d5d565b51805115614a3c5760200151907fffffffff000000000000000000000000000000000000000000000000000000006020830151167f593611990000000000000000000000000000000000000000000000000000000081145f14611c68575081611c5f8487600195516156ce565b90525b01611a57565b7fa8d2cb11000000000000000000000000000000000000000000000000000000008103611e4b575081516101208180518101031261025d57604051908161012081011067ffffffffffffffff6101208401111761032e57866118b786611d61936101208601604052611cdc602082016107ef565b8652611cea604082016107ef565b6020870152611cfb606082016107ef565b6040870152611d0c608082016153d8565b6060870152611d1d60a082016153d8565b6080870152611d5661012060c0830151928360a08a015260e081015160c08a0152611d4b61010082016107ef565b60e08a0152016107e2565b610100870152614ce6565b60a08201526101006040519173ffffffffffffffffffffffffffffffffffffffff815116602084015273ffffffffffffffffffffffffffffffffffffffff602082015116604084015273ffffffffffffffffffffffffffffffffffffffff6040820151166060840152606081015160ff809116608085015260808201511660a084015260a081015160c084015260c081015160e084015273ffffffffffffffffffffffffffffffffffffffff60e0820151168284015201511515610120820152610120815261014081019281841067ffffffffffffffff85111761032e5760019360405252611c62565b7fd90ce491000000000000000000000000000000000000000000000000000000008103611e89575081611e82848760019551615535565b9052611c62565b7fa3722546000000000000000000000000000000000000000000000000000000008103611ec0575081611e828487600195516156ce565b7f63407a49000000000000000000000000000000000000000000000000000000008103611fff5750815160e08180518101031261025d57600192611f82876118b78760405195611f0f87610312565b611f1b602082016107ef565b8752611f29604082016107ef565b6020880152611f3a606082016107ef565b6040880152611f4b608082016107ef565b6060880152611f7860e060a0830151928360808b0152611f6d60c082016107ef565b60a08b0152016107e2565b60c0880152614ce6565b608083015260c06040519273ffffffffffffffffffffffffffffffffffffffff808251166020860152806020830151166040860152806040830151166060860152806060830151166080860152608082015160a086015260a082015116828501520151151560e083015260e08252611ff9826103e8565b52611c62565b7fca6182da0000000000000000000000000000000000000000000000000000000081036120aa5760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65205246512073776170000000000000000000000000000000000000000000006064820152fd5b7f8cc7a56b0000000000000000000000000000000000000000000000000000000081036121995750815160a08180518101031261025d576001926040516120f081610378565b6120fc602084016107ef565b8152604083015160208201908152612116606085016107ef565b936040830194855260a061212c608083016107ef565b916060850192835201519261214c8b6118b78b6080850197808952614ce6565b84526040519573ffffffffffffffffffffffffffffffffffffffff938480935116602089015251604088015251166060860152511660808401525160a083015260a08252611ff982610394565b7f0ca8ebf10000000000000000000000000000000000000000000000000000000081036122595750815160608180518101031261025d57600192604051916121e083610405565b6121ec602082016107ef565b835260408101519061221c896118b78961220f606060208a0196888852016107e2565b9560408901968752614ce6565b815273ffffffffffffffffffffffffffffffffffffffff6040519451166020850152516040840152511515606083015260608252611ff9826103cc565b7feeb543140000000000000000000000000000000000000000000000000000000081036122bc575081519160208380518101031261025d576122a5866118b78660206001970151614ce6565b9060405191602083015260208252611ff9826103b0565b7f7b797563000000000000000000000000000000000000000000000000000000008103612416575081516101008180518101031261025d57600192612391876118b7876040519561230c876103e8565b612318602082016107ef565b8752612326604082016107ef565b6020880152612337606082016107ef565b6040880152612348608082016107ef565b606088015261238761010060a0830151928360808b015261236b60c082016107ef565b60a08b015261237c60e082016107e2565b60c08b0152016107e2565b60e0880152614ce6565b608083015260e06040519273ffffffffffffffffffffffffffffffffffffffff808251166020860152806020830151166040860152806040830151166060860152806060830151166080860152608082015160a086015260a08201511660c085015260c0810151151582850152015115156101008301526101008252611ff982610421565b7f55fad2fb00000000000000000000000000000000000000000000000000000000810361244d575081611e828487600195516156ce565b7f3b284cfe00000000000000000000000000000000000000000000000000000000810361251157508151918251830160a08482031261025d57600193602080612498930191016153e6565b90606082016124ac886118b7888451614ce6565b90526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015260608101516060860152015116910152565b60a08252611ff982610394565b7f74836acb0000000000000000000000000000000000000000000000000000000081036126375750815160e08180518101031261025d576001926040519161255883610312565b612564602082016107ef565b8352612572604082016107ef565b6020840152612583606082016107ef565b6040840152608081015160608401526125c8886118b7886125bb60e060a0870151968760808b015260c081015160a08b0152016107e2565b9460c08801958652614ce6565b608084015260a06040519373ffffffffffffffffffffffffffffffffffffffff808251166020870152806020830151166040870152604082015116606086015260608101516080860152608081015182860152015160c084015251151560e083015260e08252611ff9826103e8565b7f800023a10000000000000000000000000000000000000000000000000000000081036126e25760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f6520486173666c6f7720737761700000000000000000000000000000000000006064820152fd5b7f8df4a16b000000000000000000000000000000000000000000000000000000008103612719575081611e828487600195516156ce565b7fd6984a6d0000000000000000000000000000000000000000000000000000000081036127c45760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65204b796265724c4f20737761700000000000000000000000000000000000006064820152fd5b7f8f07985400000000000000000000000000000000000000000000000000000000810361280f57508151918251830160a08482031261025d57600193602080612498930191016153e6565b7fa9b3e398000000000000000000000000000000000000000000000000000000008103612846575081611e828487600195516156ce565b7f92749fe10000000000000000000000000000000000000000000000000000000081036128fc57508151918251830160a08482031261025d576001936020806128919301910161565b565b90608082016128a5886118b7888451614ce6565b90526125046040519260208401906080809173ffffffffffffffffffffffffffffffffffffffff80825116855280602083015116602086015280604083015116604086015260608201511660608501520151910152565b7f27c0cd18000000000000000000000000000000000000000000000000000000008103612a075750815160c08180518101031261025d5760019260405161294281610394565b61294e602084016107ef565b815261295c604084016107ef565b9260208201938452612970606082016107ef565b9360408301948552612984608083016107ef565b6060840190815260a0830151936129b28c6118b78c60c060808601988a8a5201519860a08601998a52614ce6565b84526040519673ffffffffffffffffffffffffffffffffffffffff8094818094511660208b01525116604089015251166060870152511660808501525160a08401525160c083015260c08252611ff982610312565b7fe756cac1000000000000000000000000000000000000000000000000000000008103612b815750815191825183019060208483031261025d57602084015167ffffffffffffffff811161025d5760a081860184031261025d57604051612a6d81610378565b602082870101519167ffffffffffffffff831161025d57600196612aa1611ff994602080612b2099019185850101016108dd565b8352612ab16040838301016107ef565b916020840192835260a0612ac96060838501016107ef565b9160408601928352612adf6080828601016107ef565b936060870194855201015191612b008d6118b78d6080890196808852614ce6565b83526040519788956020808801525160a0604088015260e0870190610922565b935173ffffffffffffffffffffffffffffffffffffffff9283809216606088015251166080860152511660a08401525160c0830152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810184528361043e565b7f48d31802000000000000000000000000000000000000000000000000000000008103612cb15750815160e08180518101031261025d57600192612c3c876118b78760405195612bd087610312565b612bdc602082016107ef565b8752612bea604082016107ef565b6020880152612bfb606082016107ef565b6040880152612c0c608082016107ef565b606088015260e060a0820151918260808a0152612c2b60c082016107ef565b60a08a0152015160c0880152614ce6565b608083015260c06040519273ffffffffffffffffffffffffffffffffffffffff808251166020860152806020830151166040860152806040830151166060860152806060830151166080860152608082015160a086015260a08201511682850152015160e083015260e08252611ff9826103e8565b7f04cca9f7000000000000000000000000000000000000000000000000000000008103612f405750908051908151820160208382031261025d57602083015167ffffffffffffffff811161025d5760a081850183031261025d5760405193612d1885610378565b612d266020838301016107ef565b85526040828201015167ffffffffffffffff811161025d5760208401603f828585010101121561025d57602081848401010151612d6281610810565b91612d70604051938461043e565b81835260208301906020870160408460051b838989010101011161025d576040818787010101915b60408460051b838989010101018310612f30575050505060208601526060828201015167ffffffffffffffff811161025d57612dde906020808601918585010101614dec565b6040860152608082820101519267ffffffffffffffff841161025d5760a08a936118b793612e1a612e2d976020808e9701918585010101614e55565b60608a0152010151806080880152614ce6565b60808301526040519160208084015260e0830173ffffffffffffffffffffffffffffffffffffffff825116604085015260208201519060a060608601528151809152602061010086019201905f905b808210612f185750505083826080612ee4611ff994612ecf604060019b9a99980151917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0928388830301868901526110a3565b906060850151908683030160a0870152614ed5565b91015160c0830152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810184528361043e565b90919260208060019286518152019401920190612e7c565b8251815260209283019201612d98565b7faa293da2000000000000000000000000000000000000000000000000000000008103612f77575081611e82848760019551615443565b7f517e7ca1000000000000000000000000000000000000000000000000000000008103612fae575081611e82848760019551615443565b7f1b96cfd40000000000000000000000000000000000000000000000000000000081036130cd575081519160c08380518101031261025d5760405190612ff382610394565b612fff602085016107ef565b825261300d604085016107ef565b602083015261301e606085016107ef565b604083015261302f608085016107ef565b606083015260c060a08501519485608085015201518060020b810361025d57613065886118b78860019860a08801958652614ce6565b608084015260806040519373ffffffffffffffffffffffffffffffffffffffff80825116602087015280602083015116604087015280604083015116606087015260608201511682860152015160a08401525160020b60c083015260c08252611ff982610312565b7f5987cf43000000000000000000000000000000000000000000000000000000008103613104575081611e82848760019551615443565b7fc43025bd00000000000000000000000000000000000000000000000000000000810361320157508151918251830160a08482031261025d5760019360208061314f9301910161565b565b906080820180517f80000000000000000000000000000000000000000000000000000000000000006131a78a6118b78a7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614ce6565b91161790526125046040519260208401906080809173ffffffffffffffffffffffffffffffffffffffff80825116855280602083015116602086015280604083015116604086015260608201511660608501520151910152565b7f63d71df3000000000000000000000000000000000000000000000000000000008103613238575081611e82848760019551615535565b7fe7e1b5cb0000000000000000000000000000000000000000000000000000000081036133445750815160c08180518101031261025d5760019260405161327e81610394565b61328a602084016107ef565b8152613298604084016107ef565b90602081019182526132ac606085016107ef565b936040820194855260808101519160608101908382526132ef8c6118b78c6132e260c060a08901519860808801998a52016107ef565b9760a08601988952614ce6565b82526040519673ffffffffffffffffffffffffffffffffffffffff8096818094511660208b015251166040890152511660608701525160808601525160a0850152511660c083015260c08252611ff982610312565b7f3ac19910000000000000000000000000000000000000000000000000000000008103613494575081516101008180518101031261025d5760019261340f876118b78760405195613394876103e8565b6133a0602082016107ef565b87526133ae604082016107ef565b60208801526133bf606082016107ef565b60408801526133d0608082016107ef565b60608801526133e160a082016107ef565b60808801526133f260c082016107ef565b60a088015261238761010060e0830151928360c08b0152016107ef565b60c083015273ffffffffffffffffffffffffffffffffffffffff60e0604051938281511660208601528260208201511660408601528260408201511660608601528260608201511660808601528260808201511660a08601528260a08201511660c086015260c0810151828601520151166101008301526101008252611ff982610421565b7f37e96a470000000000000000000000000000000000000000000000000000000081036135b25750815160e08180518101031261025d576001926040516134da81610312565b6134e6602084016107ef565b81526134f4604084016107ef565b9060208101918252613508606085016107ef565b936040820194855260808101516060830190815260a0820151906080840191825260c0830151936135578d6118b78d61354a60e060a08701998b8b52016107ef565b9860c08601998a52614ce6565b84526040519773ffffffffffffffffffffffffffffffffffffffff8097818094511660208c0152511660408a0152511660608801525160808701525160a08601525160c0850152511660e083015260e08252611ff9826103e8565b7f4a8ac7610000000000000000000000000000000000000000000000000000000081036136e55750815160e08180518101031261025d57600192604051916135f983610312565b613605602082016107ef565b83526040810151906020840190828252613621606082016107ef565b9160408601928352613635608083016107ef565b956060810196875261364960a084016107ef565b90608081019182526136858d6118b78d61367860e061366a60c08b016107ef565b9960a088019a8b52016107e2565b9960c086019a8b52614ce6565b83526040519773ffffffffffffffffffffffffffffffffffffffff80968195828095511660208d01525160408c0152511660608a015251166080880152511660a0860152511660c084015251151560e083015260e08252611ff9826103e8565b7fc8e128e40000000000000000000000000000000000000000000000000000000081036137c35750815160808180518101031261025d576001926040519161372c836103cc565b613738602082016107ef565b8352613746604082016107ef565b906020840191825260608101519061377c8a6118b78a61376f608060408b0196888852016107ef565b9560608a01968752614ce6565b81526040519473ffffffffffffffffffffffffffffffffffffffff9384809251166020880152511660408601525160608501525116608083015260808252611ff982610378565b7ffac08e6f0000000000000000000000000000000000000000000000000000000081036137fa575081611e82848760019551615443565b7fe445a7ec000000000000000000000000000000000000000000000000000000008103613831575081611e82848760019551615443565b7f944432e00000000000000000000000000000000000000000000000000000000081036138e657508151918251830160a08482031261025d5760019360208061387c930191016154dc565b9060208201613890886118b7888451614ce6565b90526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff918281511685526020810151602086015260408101516040860152826060820151166060860152015116910152565b7f0e00deaa0000000000000000000000000000000000000000000000000000000081036139c35750815160808180518101031261025d576001926040519161392d836103cc565b613939602082016107ef565b8352613947604082016107ef565b60208401908152608061395c606084016107ef565b926040860193845201519161397c8a6118b78a6060890196808852614ce6565b83526040519473ffffffffffffffffffffffffffffffffffffffff9283809251166020880152511660408601525116606084015251608083015260808252611ff982610378565b7f67f2255d000000000000000000000000000000000000000000000000000000008103613a6e5760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65205377616170563220737761700000000000000000000000000000000000006064820152fd5b7f48bad50c000000000000000000000000000000000000000000000000000000008103613aa5575081611e82848760019551615443565b7fb1f7d82d000000000000000000000000000000000000000000000000000000008103613af057508151918251830160a08482031261025d5760019360208061387c930191016154dc565b7f68abdc71000000000000000000000000000000000000000000000000000000008103613c4d5750815191825183019060208483031261025d5760208401519367ffffffffffffffff851161025d57608085820184031261025d5760405194613b58866103cc565b613b666020828401016107ef565b8652604081830101519167ffffffffffffffff831161025d57600196613b9c611ff994602080613c139901918686010101614dec565b9260208201938452613bd58c6118b78c613bc860806060878a010151966040890199888b5201016107ef565b9460608701958652614ce6565b835260405196879460208087015273ffffffffffffffffffffffffffffffffffffffff809451166040870152516080606087015260c08601906110a3565b92516080850152511660a0830152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810184528361043e565b7f152dc1cf000000000000000000000000000000000000000000000000000000008103613c84575081611e82848760019551615443565b7f98923834000000000000000000000000000000000000000000000000000000008103613dd8575081519160c08380518101031261025d5760405190613cc982610394565b613cd5602085016107ef565b825260408401516fffffffffffffffffffffffffffffffff8116810361025d57613d5b886118b7886fffffffffffffffffffffffffffffffff85613d5060c060019c849960208d0152613d2a606082016107ef565b60408d0152613d3b608082016107ef565b60608d015260a081015160808d0152016153d8565b60a08a015216614ce6565b16602083015260ff60a06040519373ffffffffffffffffffffffffffffffffffffffff8082511660208701526fffffffffffffffffffffffffffffffff6020830151166040870152806040830151166060870152606082015116608086015260808101518286015201511660c083015260c08252611ff982610312565b7e3c5f89000000000000000000000000000000000000000000000000000000008103613e825760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65204e61746976652073776170000000000000000000000000000000000000006064820152fd5b7fddfb5cb6000000000000000000000000000000000000000000000000000000008103613fa95750815160c08180518101031261025d5760019260405191613ec983610394565b613ed5602082016107ef565b8352604081015160208401818152613eef606084016107e2565b9260408601938452613f03608082016107ef565b95606081019687526fffffffffffffffffffffffffffffffff613f508d6118b78d613f4360c0613f3560a08a016107ef565b9860808901998a52016107ef565b9860a08701998a52614ce6565b1683526040519673ffffffffffffffffffffffffffffffffffffffff958694858094511660208b01525160408a0152511515606089015251166080870152511660a0850152511660c083015260c08252611ff982610312565b7f3bbc6abf0000000000000000000000000000000000000000000000000000000081036140545760846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f496e7075745363616c696e6748656c7065723a2043616e206e6f74207363616c60448201527f65204265626f70207377617000000000000000000000000000000000000000006064820152fd5b7f180a5b7600000000000000000000000000000000000000000000000000000000810361411d57508151918251830160a08482031261025d5760019360208061409f9301910161532f565b90602082016fffffffffffffffffffffffffffffffff6140c4896118b7898551614ce6565b1690526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855260208101516020860152826040820151166040860152826060820151166060860152015116910152565b7f63123dbb000000000000000000000000000000000000000000000000000000008103614154575081611e82848760019551615194565b7ff9c357e00000000000000000000000000000000000000000000000000000000081036141f75750815160408180518101031261025d576001926040519161419b836103b0565b6fffffffffffffffffffffffffffffffff6141d5896118b7896141c86040602088015197888b52016107e2565b9560208901968752614ce6565b16809352604051926020840152511515604083015260408252611ff982610405565b7fd883ad9f0000000000000000000000000000000000000000000000000000000081036142a457508151918251830160408482031261025d5760019360208061424293019101615292565b906fffffffffffffffffffffffffffffffff614263886118b7888651614ce6565b16825261429760405192602084019073ffffffffffffffffffffffffffffffffffffffff6020809280518552015116910152565b60408252611ff982610405565b7f0343ecaf0000000000000000000000000000000000000000000000000000000081036142db575081611e828487600195516152bc565b7f020918a10000000000000000000000000000000000000000000000000000000081036143c057508151918251830160408482031261025d57600193602080614326930191016151dc565b90602082016fffffffffffffffffffffffffffffffff61434d896118b78984865116614ce6565b167f8000000000000000000000000000000000000000000000000000000000000000868351908060ff92831c145f146143b857905b1b161790526142976040519260208401906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b505f90614382565b7f95d02f7d0000000000000000000000000000000000000000000000000000000081036144a157508151918251830160408482031261025d5760019360208061440b93019101615292565b906fffffffffffffffffffffffffffffffff61442e886118b78884875116614ce6565b167f8000000000000000000000000000000000000000000000000000000000000000858451908060ff92831c145f1461449957905b1b1617825261429760405192602084019073ffffffffffffffffffffffffffffffffffffffff6020809280518552015116910152565b505f90614463565b7fc390adea00000000000000000000000000000000000000000000000000000000810361456b57508151918251830160808482031261025d576001936020806144ec9301910161538c565b90602082016fffffffffffffffffffffffffffffffff614511896118b7898551614ce6565b16905261455e6040519260208401906060908173ffffffffffffffffffffffffffffffffffffffff9182815116855260208101516020860152826040820151166040860152015116910152565b60808252611ff982610378565b7fc9989fac0000000000000000000000000000000000000000000000000000000081036145a2575081611e82848760019551615194565b7f5829bd520000000000000000000000000000000000000000000000000000000081036145d9575081611e82848760019551615194565b7f87ab3c27000000000000000000000000000000000000000000000000000000008103614610575081611e828487600195516150ef565b7fba176e5c00000000000000000000000000000000000000000000000000000000810361465b57508151918251830160808482031261025d576001936020806144ec9301910161538c565b7fe937b9a900000000000000000000000000000000000000000000000000000000810361476557508151918251830160a08482031261025d576001936020806146a69301910161532f565b90602082016fffffffffffffffffffffffffffffffff6146cd896118b78984865116614ce6565b167f8000000000000000000000000000000000000000000000000000000000000000868351908060ff92831c145f1461475d57905b1b161790526125046040519260208401906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855260208101516020860152826040820151166040860152826060820151166060860152015116910152565b505f90614702565b7f323b615300000000000000000000000000000000000000000000000000000000810361479c575081611e82848760019551615194565b7ff17912eb0000000000000000000000000000000000000000000000000000000081036147d3575081611e82848760019551615194565b7fcebf718d00000000000000000000000000000000000000000000000000000000810361480a575081611e828487600195516152bc565b7fa8e60da0000000000000000000000000000000000000000000000000000000008103614841575081611e8284876001955161520b565b7fd5c275ad000000000000000000000000000000000000000000000000000000008103614878575081611e8284876001955161520b565b7fac40622c00000000000000000000000000000000000000000000000000000000810361494c575081519160208380518101031261025d5760206001930151906fffffffffffffffffffffffffffffffff6148d9886118b788848716614ce6565b16848060ff94851c145f14614924577f8000000000000000000000000000000000000000000000000000000000000000905b604051941b1617602083015260208252611ff9826103b0565b507f80000000000000000000000000000000000000000000000000000000000000005f61490b565b7fe93d0ac7000000000000000000000000000000000000000000000000000000008103614983575081611e82848760019551615194565b7fd1019fd000000000000000000000000000000000000000000000000000000000036149b85781611e828487600195516150ef565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4167677265676174696f6e4578656375746f723a204465782074797065206e6f60448201527f7420737570706f727465640000000000000000000000000000000000000000006064820152fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b835167ffffffffffffffff811161025d576020888a0101605f82858a8d01010101121561025d5760408184898c010101015188614aa582610810565b92614ab3604051948561043e565b8284526020808501928d01018c8b0187018201600585901b016060011161025d578960608d8389838282878601010101945b8860051b9301010101018110614b085750505090825250602093840193016119b3565b80519267ffffffffffffffff841161025d5760407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08f8f968f8c889184010101019687910103011261025d5760405193614b61856103b0565b60608101519467ffffffffffffffff861161025d578f918f8f97606095889460808f95614b9b602096958b8880988d0101918401016108dd565b835201518382015281520195019496614ae5565b8282614bbe9296939496614d71565b91815191602092810191838301848385031261025d57848301519267ffffffffffffffff9384811161025d5760a091018095031261025d5760405197614c0389610378565b8585015184811161025d578287614c1c92880101614dec565b8952604085015184811161025d578287614c3892880101610828565b93868a01948552606086015181811161025d578388614c5992890101614e55565b9260408b0193845260808701519660608c0197885260a081015192831161025d57614c86920188016108dd565b9260808a019384528951515f5b818110614cb657505061186b94926117eb8593611854936118979a999751614fb4565b80614ccc846118b7876118b16001968d51614d5d565b614cd7828a51614d5d565b5201614c93565b509150509190565b81810292918115918404141715614cf957565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8115614d30570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b8051821015614a3c5760209160051b010190565b91614d7a61167c565b506101008301614d8f836118b7848451614ce6565b80825215614de2575b508060e0840152604083015151915f5b838110614db6575050505090565b60019060608601614ddb82614dd4866118b7896118b1858851614d5d565b9251614d5d565b5201614da8565b600190525f614d98565b9080601f8301121561025d57815190602091614e0781610810565b93614e15604051958661043e565b81855260208086019260051b82010192831161025d57602001905b828210614e3e575050505090565b838091614e4a846107ef565b815201910190614e30565b81601f8201121561025d57805191602091614e6f84610810565b93614e7d604051958661043e565b808552838086019160051b8301019280841161025d57848301915b848310614ea85750505050505090565b825167ffffffffffffffff811161025d578691614eca848480948901016108dd565b815201920191614e98565b90808251908181526020809101926020808460051b8301019501935f915b848310614f035750505050505090565b9091929394958480614f3f837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086600196030187528a51610922565b9801930193019194939290614ef3565b15614f5657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f457863656564656420747970652072616e6765000000000000000000000000006044820152fd5b919082918251906020918281115f1461505c5750835160409485918101031261025d577fffffffffffffffffffffffffffffffff0000000000000000000000000000000084805196615005886103b0565b8481015188520151615040615037858901968388526118b76fffffffffffffffffffffffffffffffff96878616614ce6565b93841115614f4f565b1617825282519351908401525181830152815261091f81610405565b9091809394508114615070575b5050505090565b918480929382959601031261025d576150a7836150b0920151946118b76fffffffffffffffffffffffffffffffff94858816614ce6565b91821115614f4f565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000006040519316178183015281526150e6816103b0565b5f808080615069565b9160608380518101031261025d576fffffffffffffffffffffffffffffffff6151556040519361511e85610405565b61512a602087016107ef565b85526118b760408701519461514860606020890199888b52016107ef565b9560408801968752614ce6565b1683526040519273ffffffffffffffffffffffffffffffffffffffff809351166020850152516040840152511660608201526060815261091f816103cc565b919060208380518101031261025d576118b76151c59260206fffffffffffffffffffffffffffffffff950151614ce6565b166040519060208201526020815261091f816103b0565b919082604091031261025d576040516151f4816103b0565b6020808294615202816107ef565b84520151910152565b919091805181019060408183031261025d57615241615251916020806fffffffffffffffffffffffffffffffff950191016151dc565b936118b760208601948551614ce6565b1690526152856040519160208301906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b6040815261091f81610405565b919082604091031261025d576040516152aa816103b0565b602061109e81839580518552016107ef565b90815182019060408383031261025d576118b76152f36fffffffffffffffffffffffffffffffff946020806152fb96019101615292565b948551614ce6565b16815261528560405191602083019073ffffffffffffffffffffffffffffffffffffffff6020809280518552015116910152565b91908260a091031261025d5760405161534781610378565b608061109e818395615358816107ef565b855260208101516020860152615370604082016107ef565b6040860152615381606082016107ef565b6060860152016107ef565b919082608091031261025d576040516153a4816103cc565b606061109e8183956153b5816107ef565b8552602081015160208601526153cd604082016107ef565b6040860152016107ef565b519060ff8216820361025d57565b91908260a091031261025d576040516153fe81610378565b608061109e81839561540f816107ef565b855261541d602082016107ef565b602086015261542e604082016107ef565b604086015260608101516060860152016107ef565b9190918051810160a08282031261025d5761547791602080615467930191016153e6565b926118b760608501938451614ce6565b90526154cf6040519160208301906080908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015260608101516060860152015116910152565b60a0815261091f81610394565b91908260a091031261025d576040516154f481610378565b608061109e818395615505816107ef565b85526020810151602086015260408101516040860152615381606082016107ef565b519081600f0b820361025d57565b9190829182516101009485918101031261025d5760a08493604051958694859461555e866103e8565b61556a602085016107ef565b86526155f561557b604086016107ef565b92602088019384526118b7615592606088016107ef565b9360408a019485528960e06155eb6155ac60808c01615527565b99606084019a8b526155bf8d8d01615527565b9b608085019c8d5260c08101519d8e95019d8e5260c06155e08583016107e2565b9f019e8f52016107e2565b9c019b8c52614ce6565b85526040519873ffffffffffffffffffffffffffffffffffffffff92838092511660208c0152511660408a01525116606088015251600f0b608087015251600f0b60a08601525160c085015251151560e084015251151581830152815261091f81610421565b91908260a091031261025d5760405161567381610378565b6080808294615681816107ef565b845261568f602082016107ef565b60208501526156a0604082016107ef565b60408501526156b1606082016107ef565b60608501520151910152565b519063ffffffff8216820361025d57565b80919281516101009384918101031261025d57818060c092604051906156f3826103e8565b6156ff602084016107ef565b825261570d604084016107ef565b916020810192835261578d615724606086016107ef565b99604083019a8b526118b761573b608088016107ef565b94606085019586526157808c61577260e061576460a08d01519e8f9d60808c019e8f52016156bd565b9c60a08a019d8e52016156bd565b9c60c088019d8e52016156bd565b9960e086019a8b52614ce6565b84526040519873ffffffffffffffffffffffffffffffffffffffff8094818094511660208d0152511660408b015251166060890152511660808701525160a08601525163ffffffff928380921660c0870152511660e0850152511681830152815261091f8161042156fea2646970667358221220d0795bdc5bd2dd32e5c1d0a36090ad6cd21b3d392ef24a8e99c59565c715baa464736f6c63430008180033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.