MATIC Price: $0.534752 (-0.67%)
Gas: 30.9 GWei
 

Sponsored

Transaction Hash
Method
Block
From
To
Zap Native593434422024-07-14 8:46:276 days ago1720946787IN
ApeSwap: Polygon Zap
5 MATIC0.0081160530.00000004
Zap Native578028812024-06-05 16:36:5345 days ago1717605413IN
ApeSwap: Polygon Zap
0.65284394 MATIC0.004143350
Zap Native578020402024-06-05 16:05:5945 days ago1717603559IN
ApeSwap: Polygon Zap
1 MATIC0.013252950
Zap Native575625672024-05-30 10:09:4651 days ago1717063786IN
ApeSwap: Polygon Zap
0.1 MATIC0.01159550
Zap572195292024-05-21 10:49:2660 days ago1716288566IN
ApeSwap: Polygon Zap
0 MATIC0.0070958530.07393582
Zap Native567538502024-05-09 7:43:0572 days ago1715240585IN
ApeSwap: Polygon Zap
1 MATIC0.0102102941.1775008
Zap Native562043492024-04-24 15:37:4687 days ago1713973066IN
ApeSwap: Polygon Zap
0.1 MATIC0.05409981235.06633459
Zap Native559879422024-04-19 1:22:5193 days ago1713489771IN
ApeSwap: Polygon Zap
2 MATIC0.07307413192.21639879
Zap Native559293902024-04-17 13:37:2994 days ago1713361049IN
ApeSwap: Polygon Zap
0.1 MATIC0.06363102256.66987435
Zap Native558778852024-04-16 5:07:0096 days ago1713244020IN
ApeSwap: Polygon Zap
0.1 MATIC0.0251073498.19870889
Zap Native557340332024-04-12 9:56:4599 days ago1712915805IN
ApeSwap: Polygon Zap
1 MATIC0.07030934304.55667717
Zap Native556517992024-04-10 4:39:18102 days ago1712723958IN
ApeSwap: Polygon Zap
1 MATIC0.03899905157.27454761
Zap Native555649762024-04-07 22:22:24104 days ago1712528544IN
ApeSwap: Polygon Zap
1 MATIC0.0397587150
Zap Native555649082024-04-07 22:19:58104 days ago1712528398IN
ApeSwap: Polygon Zap
1 MATIC0.0333465150
Zap555640982024-04-07 21:50:47104 days ago1712526647IN
ApeSwap: Polygon Zap
0 MATIC0.0153954150
Zap555633352024-04-07 21:23:01104 days ago1712524981IN
ApeSwap: Polygon Zap
0 MATIC0.0556236150
Zap Native555630572024-04-07 21:12:46104 days ago1712524366IN
ApeSwap: Polygon Zap
0.5 MATIC0.03263595150
Zap Native555630132024-04-07 21:11:12104 days ago1712524272IN
ApeSwap: Polygon Zap
1 MATIC0.03260325150
Zap555613322024-04-07 20:09:27104 days ago1712520567IN
ApeSwap: Polygon Zap
0 MATIC0.0164770572
Zap Native555562222024-04-07 17:03:29104 days ago1712509409IN
ApeSwap: Polygon Zap
1 MATIC0.0480612200
Zap Native555558512024-04-07 16:49:49104 days ago1712508589IN
ApeSwap: Polygon Zap
1 MATIC0.0446412200
Zap555539992024-04-07 15:42:05104 days ago1712504525IN
ApeSwap: Polygon Zap
0 MATIC0.0411761189
Zap Native555532442024-04-07 15:14:17104 days ago1712502857IN
ApeSwap: Polygon Zap
1 MATIC0.05164025233
Zap Native555528862024-04-07 15:00:33104 days ago1712502033IN
ApeSwap: Polygon Zap
1 MATIC0.04317573195
Zap Native555496642024-04-07 13:00:35104 days ago1712494835IN
ApeSwap: Polygon Zap
7 MATIC0.02875502136
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
593434422024-07-14 8:46:276 days ago1720946787
ApeSwap: Polygon Zap
5 MATIC
578028812024-06-05 16:36:5345 days ago1717605413
ApeSwap: Polygon Zap
0.65284394 MATIC
578020402024-06-05 16:05:5945 days ago1717603559
ApeSwap: Polygon Zap
0.0009891 MATIC
578020402024-06-05 16:05:5945 days ago1717603559
ApeSwap: Polygon Zap
0.0009891 MATIC
578020402024-06-05 16:05:5945 days ago1717603559
ApeSwap: Polygon Zap
1 MATIC
575625672024-05-30 10:09:4651 days ago1717063786
ApeSwap: Polygon Zap
0.1 MATIC
567538502024-05-09 7:43:0572 days ago1715240585
ApeSwap: Polygon Zap
0.00098906 MATIC
567538502024-05-09 7:43:0572 days ago1715240585
ApeSwap: Polygon Zap
0.00098906 MATIC
567538502024-05-09 7:43:0572 days ago1715240585
ApeSwap: Polygon Zap
1 MATIC
562043492024-04-24 15:37:4687 days ago1713973066
ApeSwap: Polygon Zap
0.00009998 MATIC
562043492024-04-24 15:37:4687 days ago1713973066
ApeSwap: Polygon Zap
0.00009998 MATIC
562043492024-04-24 15:37:4687 days ago1713973066
ApeSwap: Polygon Zap
0.1 MATIC
559879422024-04-19 1:22:5193 days ago1713489771
ApeSwap: Polygon Zap
0.03084219 MATIC
559879422024-04-19 1:22:5193 days ago1713489771
ApeSwap: Polygon Zap
0.03084219 MATIC
559879422024-04-19 1:22:5193 days ago1713489771
ApeSwap: Polygon Zap
2 MATIC
559293902024-04-17 13:37:2994 days ago1713361049
ApeSwap: Polygon Zap
0.00009989 MATIC
559293902024-04-17 13:37:2994 days ago1713361049
ApeSwap: Polygon Zap
0.00009989 MATIC
559293902024-04-17 13:37:2994 days ago1713361049
ApeSwap: Polygon Zap
0.1 MATIC
558778852024-04-16 5:07:0096 days ago1713244020
ApeSwap: Polygon Zap
0.000062 MATIC
558778852024-04-16 5:07:0096 days ago1713244020
ApeSwap: Polygon Zap
0.000062 MATIC
558778852024-04-16 5:07:0096 days ago1713244020
ApeSwap: Polygon Zap
0.1 MATIC
557340332024-04-12 9:56:4599 days ago1712915805
ApeSwap: Polygon Zap
0.00098881 MATIC
557340332024-04-12 9:56:4599 days ago1712915805
ApeSwap: Polygon Zap
0.00098881 MATIC
557340332024-04-12 9:56:4599 days ago1712915805
ApeSwap: Polygon Zap
1 MATIC
556517992024-04-10 4:39:18102 days ago1712723958
ApeSwap: Polygon Zap
0.00098881 MATIC
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ApeSwapZapFullV3

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 20 : ApeSwapZapFullV3.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.15;

/*
  ______                     ______                                 
 /      \                   /      \                                
|  β–“β–“β–“β–“β–“β–“\ ______   ______ |  β–“β–“β–“β–“β–“β–“\__   __   __  ______   ______  
| β–“β–“__| β–“β–“/      \ /      \| β–“β–“___\β–“β–“  \ |  \ |  \|      \ /      \ 
| β–“β–“    β–“β–“  β–“β–“β–“β–“β–“β–“\  β–“β–“β–“β–“β–“β–“\\β–“β–“    \| β–“β–“ | β–“β–“ | β–“β–“ \β–“β–“β–“β–“β–“β–“\  β–“β–“β–“β–“β–“β–“\
| β–“β–“β–“β–“β–“β–“β–“β–“ β–“β–“  | β–“β–“ β–“β–“    β–“β–“_\β–“β–“β–“β–“β–“β–“\ β–“β–“ | β–“β–“ | β–“β–“/      β–“β–“ β–“β–“  | β–“β–“
| β–“β–“  | β–“β–“ β–“β–“__/ β–“β–“ β–“β–“β–“β–“β–“β–“β–“β–“  \__| β–“β–“ β–“β–“_/ β–“β–“_/ β–“β–“  β–“β–“β–“β–“β–“β–“β–“ β–“β–“__/ β–“β–“
| β–“β–“  | β–“β–“ β–“β–“    β–“β–“\β–“β–“     \\β–“β–“    β–“β–“\β–“β–“   β–“β–“   β–“β–“\β–“β–“    β–“β–“ β–“β–“    β–“β–“
 \β–“β–“   \β–“β–“ β–“β–“β–“β–“β–“β–“β–“  \β–“β–“β–“β–“β–“β–“β–“ \β–“β–“β–“β–“β–“β–“  \β–“β–“β–“β–“β–“\β–“β–“β–“β–“  \β–“β–“β–“β–“β–“β–“β–“ β–“β–“β–“β–“β–“β–“β–“ 
         | β–“β–“                                             | β–“β–“      
         | β–“β–“                                             | β–“β–“      
          \β–“β–“                                              \β–“β–“         

 * App:             https://apeswap.finance
 * Medium:          https://ape-swap.medium.com
 * Twitter:         https://twitter.com/ape_swap
 * Discord:         https://discord.com/invite/apeswap
 * Telegram:        https://t.me/ape_swap
 * Announcements:   https://t.me/ape_swap_news
 * GitHub:          https://github.com/ApeSwapFinance
 */

import "./ApeSwapZap.sol";
import "./extensions/bills/ApeSwapZapTBills.sol";
import "./extensions/ApeSwapZapLPMigrator.sol";
import "./extensions/pools/ApeSwapZapPools.sol";
import "./extensions/pools/lib/ITreasury.sol";
import "./extensions/farms/ApeSwapZapMiniApeV2.sol";
import "./extensions/farms/lib/IMiniApeV2.sol";
import "./lib/IApeRouter02.sol";

contract ApeSwapZapFullV3 is
    ApeSwapZap,
    ApeSwapZapTBills,
    ApeSwapZapLPMigrator,
    ApeSwapZapPools,
    ApeSwapZapMiniApeV2
{
    constructor(IApeRouter02 _router)
        ApeSwapZap(_router)
        ApeSwapZapLPMigrator(_router)
        ApeSwapZapPools()
        ApeSwapZapMiniApeV2()
    {}
}

File 2 of 20 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 5 of 20 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 6 of 20 : IWETH.sol
// SPDX-License-Identifier: MIT
 pragma solidity 0.8.15;

interface IWETH {
    function deposit() external payable;

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

    function withdraw(uint256) external;
}

File 7 of 20 : IApeRouter02.sol
// SPDX-License-Identifier: MIT
 pragma solidity 0.8.15;

import "./IApeRouter01.sol";

interface IApeRouter02 is IApeRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

File 8 of 20 : IApeRouter01.sol
// SPDX-License-Identifier: MIT
 pragma solidity 0.8.15;

interface IApeRouter01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);

    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
}

File 9 of 20 : IApePair.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.6.6;

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

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

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

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

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

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

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

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to)
        external
        returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

File 10 of 20 : IApeFactory.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.6.6;

interface IApeFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function INIT_CODE_PAIR_HASH() external view returns (bytes32);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

File 11 of 20 : ITreasury.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

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

interface ITreasury {
    function adminAddress() external view returns (address);

    function banana() external view returns (IERC20);

    function bananaReserves() external view returns (uint256);

    function buy(uint256 _amount) external;

    function buyFee() external view returns (uint256);

    function emergencyWithdraw(uint256 _amount) external;

    function goldenBanana() external view returns (IERC20);

    function goldenBananaReserves() external view returns (uint256);

    function maxBuyFee() external view returns (uint256);

    function owner() external view returns (address);

    function renounceOwnership() external;

    function sell(uint256 _amount) external;

    function setAdmin(address _adminAddress) external;

    function setBuyFee(uint256 _fee) external;

    function transferOwnership(address newOwner) external;
}

File 12 of 20 : IBEP20RewardApeV5.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

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

interface IBEP20RewardApeV5 {
    function REWARD_TOKEN() external view returns (IERC20);

    function STAKE_TOKEN() external view returns (IERC20);

    function bonusEndBlock() external view returns (uint256);

    function owner() external view returns (address);

    function poolInfo()
        external
        view
        returns (
            address lpToken,
            uint256 allocPoint,
            uint256 lastRewardBlock,
            uint256 accRewardTokenPerShare
        );

    function renounceOwnership() external;

    function rewardPerBlock() external view returns (uint256);

    function startBlock() external view returns (uint256);

    function totalRewardsAllocated() external view returns (uint256);

    function totalRewardsPaid() external view returns (uint256);

    function totalStaked() external view returns (uint256);

    function transferOwnership(address newOwner) external;

    function userInfo(address)
        external
        view
        returns (uint256 amount, uint256 rewardDebt);

    function initialize(
        address _stakeToken,
        address _rewardToken,
        uint256 _rewardPerBlock,
        uint256 _startBlock,
        uint256 _bonusEndBlock
    ) external;

    function getMultiplier(uint256 _from, uint256 _to)
        external
        view
        returns (uint256);

    function setBonusEndBlock(uint256 _bonusEndBlock) external;

    function pendingReward(address _user) external view returns (uint256);

    function updatePool() external;

    function deposit(uint256 _amount) external;

    function depositTo(uint256 _amount, address _user) external;

    function withdraw(uint256 _amount) external;

    function rewardBalance() external view returns (uint256);

    function getUnharvestedRewards() external view returns (uint256);

    function depositRewards(uint256 _amount) external;

    function totalStakeTokenBalance() external view returns (uint256);

    function getStakeTokenFeeBalance() external view returns (uint256);

    function setRewardPerBlock(uint256 _rewardPerBlock) external;

    function skimStakeTokenFees(address _to) external;

    function emergencyWithdraw() external;

    function emergencyRewardWithdraw(uint256 _amount) external;

    function sweepToken(address token) external;
}

File 13 of 20 : ApeSwapZapPools.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "../../ApeSwapZap.sol";
import "./lib/IBEP20RewardApeV5.sol";
import "./lib/ITreasury.sol";

abstract contract ApeSwapZapPools is ApeSwapZap {
    using SafeERC20 for IERC20;

    event ZapLPPool(
        IERC20 inputToken,
        uint256 inputAmount,
        IBEP20RewardApeV5 pool
    );
    event ZapLPPoolNative(uint256 inputAmount, IBEP20RewardApeV5 pool);
    event ZapSingleAssetPool(
        IERC20 inputToken,
        uint256 inputAmount,
        IBEP20RewardApeV5 pool
    );
    event ZapSingleAssetPoolNative(
        uint256 inputAmount,
        IBEP20RewardApeV5 pool
    );

    constructor() {
    }

    /// @notice Zap token into banana/gnana pool
    /// @param inputToken Input token to zap
    /// @param inputAmount Amount of input tokens to zap
    /// @param path Path from input token to stake token
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param pool Pool address
    function zapSingleAssetPool(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] calldata path,
        uint256 minAmountsSwap,
        uint256 deadline,
        IBEP20RewardApeV5 pool
    ) external nonReentrant {
        uint256 balanceBefore = _getBalance(inputToken);
        inputToken.safeTransferFrom(msg.sender, address(this), inputAmount);
        inputAmount = _getBalance(inputToken) - balanceBefore;

        __zapInternalSingleAssetPool(
            inputToken,
            inputAmount,
            path,
            minAmountsSwap,
            deadline,
            pool
        );
        emit ZapSingleAssetPool(inputToken, inputAmount, pool);
    }

    /// @notice Zap native into banana/gnana pool
    /// @param path Path from input token to stake token
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param pool Pool address
    function zapSingleAssetPoolNative(
        address[] calldata path,
        uint256 minAmountsSwap,
        uint256 deadline,
        IBEP20RewardApeV5 pool
    ) external payable nonReentrant {
        uint256 inputAmount = msg.value;
        IERC20 inputToken = IERC20(WNATIVE);
        IWETH(WNATIVE).deposit{ value: inputAmount }();

        __zapInternalSingleAssetPool(
            inputToken,
            inputAmount,
            path,
            minAmountsSwap,
            deadline,
            pool
        );
        emit ZapSingleAssetPoolNative(inputAmount, pool);
    }

    /// @notice Zap token into banana/gnana pool
    /// @param inputToken Input token to zap
    /// @param inputAmount Amount of input tokens to zap
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param pool Pool address
    function zapLPPool(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        uint256 deadline,
        IBEP20RewardApeV5 pool
    ) external nonReentrant {
        IApePair pair = IApePair(address(pool.STAKE_TOKEN()));
        require(
            (lpTokens[0] == pair.token0() &&
                lpTokens[1] == pair.token1()) ||
                (lpTokens[1] == pair.token0() &&
                    lpTokens[0] == pair.token1()),
            "ApeSwapZap: Wrong LP pair for Pool"
        );

        _zapInternal(
            inputToken,
            inputAmount,
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            address(this),
            deadline
        );

        uint256 balance = pair.balanceOf(address(this));
        pair.approve(address(pool), balance);
        pool.depositTo(balance, msg.sender);
        pair.approve(address(pool), 0);
        emit ZapLPPool(inputToken, inputAmount, pool);
    }

    /// @notice Zap native into banana/gnana pool
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param pool Pool address
    function zapLPPoolNative(
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        uint256 deadline,
        IBEP20RewardApeV5 pool
    ) external payable nonReentrant {
        IApePair pair = IApePair(address(pool.STAKE_TOKEN()));
        require(
            (lpTokens[0] == pair.token0() &&
                lpTokens[1] == pair.token1()) ||
                (lpTokens[1] == pair.token0() &&
                    lpTokens[0] == pair.token1()),
            "ApeSwapZap: Wrong LP pair for Pool"
        );

        _zapNativeInternal(
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            address(this),
            deadline
        );

        uint256 balance = pair.balanceOf(address(this));
        pair.approve(address(pool), balance);
        pool.depositTo(balance, msg.sender);
        pair.approve(address(pool), 0);
        emit ZapLPPoolNative(msg.value, pool);
    }

        /// @notice Zap token into banana/gnana pool
    /// @param inputToken Input token to zap
    /// @param inputAmount Amount of input tokens to zap
    /// @param path Path from input token to stake token
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param pool Pool address
    function __zapInternalSingleAssetPool(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] calldata path,
        uint256 minAmountsSwap,
        uint256 deadline,
        IBEP20RewardApeV5 pool
    ) internal {
        IERC20 stakeToken = pool.STAKE_TOKEN();

        uint256 amount = inputAmount;

        if (inputToken != stakeToken) {
            require(
                path[0] == address(inputToken),
                "ApeSwapZap: wrong path path[0]"
            );
            require(
                path[path.length - 1] == address(stakeToken),
                "ApeSwapZap: wrong path path[-1]"
            );

            inputToken.approve(address(router), inputAmount);
            uint256[] memory amounts = router.swapExactTokensForTokens(
                inputAmount,
                minAmountsSwap,
                path,
                address(this),
                deadline
            );
            amount = amounts[amounts.length - 1];
        }

        stakeToken.approve(address(pool), amount);
        pool.depositTo(amount, msg.sender);
        stakeToken.approve(address(pool), 0);
    }
}

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

interface IMiniApeV2 {
    function lpToken(uint256 pid) external returns (address);

    function deposit(uint256 pid, uint256 amount, address to) external;
}

File 15 of 20 : ApeSwapZapMiniApeV2.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "../../ApeSwapZap.sol";
import "./lib/IMiniApeV2.sol";

abstract contract ApeSwapZapMiniApeV2 is ApeSwapZap {
    using SafeERC20 for IERC20;

    event ZapMiniApeV2(IERC20 inputToken, uint256 inputAmount, uint256 pid);
    event ZapMiniApeV2Native(uint256 inputAmount, uint256 pid);

    constructor() {}

    /// @notice Zap token into miniApev2 style dual farm
    /// @param inputToken Input token to zap
    /// @param inputAmount Amount of input tokens to zap
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param miniApe The main dualfarm contract
    /// @param pid Dual farm pid
    function zapMiniApeV2(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        uint256 deadline,
        IMiniApeV2 miniApe,
        uint256 pid
    ) external nonReentrant {
        IApePair pair = IApePair(miniApe.lpToken(pid));
        require(
            (lpTokens[0] == pair.token0() && lpTokens[1] == pair.token1()) ||
                (lpTokens[1] == pair.token0() && lpTokens[0] == pair.token1()),
            "ApeSwapZap: Wrong LP pair for MiniApe"
        );

        _zapInternal(
            inputToken,
            inputAmount,
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            address(this),
            deadline
        );

        uint256 balance = pair.balanceOf(address(this));
        pair.approve(address(miniApe), balance);
        miniApe.deposit(pid, balance, msg.sender);
        pair.approve(address(miniApe), 0);
        emit ZapMiniApeV2(inputToken, inputAmount, pid);
    }

    /// @notice Zap native into miniApev2 style dual farm
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param miniApe The main dualfarm contract
    /// @param pid Dual Farm pid
    function zapMiniApeV2Native(
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        uint256 deadline,
        IMiniApeV2 miniApe,
        uint256 pid
    ) external payable nonReentrant {
        IApePair pair = IApePair(miniApe.lpToken(pid));
        require(
            (lpTokens[0] == pair.token0() && lpTokens[1] == pair.token1()) ||
                (lpTokens[1] == pair.token0() && lpTokens[0] == pair.token1()),
            "ApeSwapZap: Wrong LP pair for Dual Farm"
        );

        _zapNativeInternal(
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            address(this),
            deadline
        );

        uint256 balance = pair.balanceOf(address(this));
        pair.approve(address(miniApe), balance);
        miniApe.deposit(pid, balance, msg.sender);
        pair.approve(address(miniApe), 0);
        emit ZapMiniApeV2Native(msg.value, pid);
    }
}

File 16 of 20 : ICustomBill.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

interface ICustomBill {
    function principalToken() external returns (address);

    function deposit(
        uint256 _amount,
        uint256 _maxPrice,
        address _depositor
    ) external returns (uint256);
}

File 17 of 20 : ApeSwapZapTBills.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "../../ApeSwapZap.sol";
import "./lib/ICustomBill.sol";

abstract contract ApeSwapZapTBills is ApeSwapZap {
    event ZapTBill(IERC20 inputToken, uint256 inputAmount, ICustomBill bill);
    event ZapTBillNative(uint256 inputAmount, ICustomBill bill);

    /// @notice Zap single token to LP
    /// @param inputToken Input token to zap
    /// @param inputAmount Amount of input tokens to zap
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param bill Treasury bill address
    /// @param maxPrice Max price of treasury bill
    function zapTBill(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        uint256 deadline,
        ICustomBill bill,
        uint256 maxPrice
    ) external nonReentrant {
        IApePair pair = IApePair(bill.principalToken());
        require(
            (lpTokens[0] == pair.token0() &&
                lpTokens[1] == pair.token1()) ||
                (lpTokens[1] == pair.token0() &&
                    lpTokens[0] == pair.token1()),
            "ApeSwapZap: Wrong LP pair for TBill"
        );

        _zapInternal(
            inputToken,
            inputAmount,
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            address(this),
            deadline
        );

        uint256 balance = pair.balanceOf(address(this));
        pair.approve(address(bill), balance);
        bill.deposit(balance, maxPrice, msg.sender);
        pair.approve(address(bill), 0);
        emit ZapTBill(inputToken, inputAmount, bill);
    }

    /// @notice Zap native token to Treasury Bill
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    /// @param bill Treasury bill address
    /// @param maxPrice Max price of treasury bill
    function zapTBillNative(
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        uint256 deadline,
        ICustomBill bill,
        uint256 maxPrice
    ) external payable nonReentrant {
        IApePair pair = IApePair(bill.principalToken());
        require(
            (lpTokens[0] == pair.token0() &&
                lpTokens[1] == pair.token1()) ||
                (lpTokens[1] == pair.token0() &&
                    lpTokens[0] == pair.token1()),
            "ApeSwapZap: Wrong LP pair for TBill"
        );

        _zapNativeInternal(
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            address(this),
            deadline
        );

        uint256 balance = pair.balanceOf(address(this));
        pair.approve(address(bill), balance);
        bill.deposit(balance, maxPrice, msg.sender);
        pair.approve(address(bill), 0);
        emit ZapTBillNative(msg.value, bill);
    }
}

File 18 of 20 : ApeSwapZapLPMigrator.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../lib/IApeRouter02.sol";
import "../lib/IApePair.sol";

abstract contract ApeSwapZapLPMigrator is ReentrancyGuard {
    using SafeERC20 for IERC20;

    IApeRouter02 public immutable apeRouter;

    event LPMigrated(
        IApePair lp,
        IApeRouter02 fromRouter,
        IApeRouter02 toRouter,
        uint256 amount
    );

    constructor(IApeRouter02 router) {
        apeRouter = router;
    }

    /// @notice Zap non APE-LPs to APE-LPs
    /// @param router The non APE-LP router
    /// @param lp LP address to zap
    /// @param amount Amount of LPs to zap
    /// @param amountAMinRemove The minimum amount of token0 to receive after removing liquidity
    /// @param amountBMinRemove The minimum amount of token1 to receive after removing liquidity
    /// @param amountAMinAdd The minimum amount of token0 to add to APE-LP on add liquidity
    /// @param amountBMinAdd The minimum amount of token1 to add to APE-LP on add liquidity
    /// @param deadline Unix timestamp after which the transaction will revert
    function zapLPMigrator(
        IApeRouter02 router,
        IApePair lp,
        uint256 amount,
        uint256 amountAMinRemove,
        uint256 amountBMinRemove,
        uint256 amountAMinAdd,
        uint256 amountBMinAdd,
        uint256 deadline
    ) external nonReentrant {
        address token0 = lp.token0();
        address token1 = lp.token1();

        IERC20(address(lp)).safeTransferFrom(msg.sender, address(this), amount);
        lp.approve(address(router), amount);
        (uint256 amountAReceived, uint256 amountBReceived) = router
            .removeLiquidity(
                token0,
                token1,
                amount,
                amountAMinRemove,
                amountBMinRemove,
                address(this),
                deadline
            );

        IERC20(token0).approve(address(apeRouter), amountAReceived);
        IERC20(token1).approve(address(apeRouter), amountBReceived);
        (uint256 amountASent, uint256 amountBSent, ) = apeRouter.addLiquidity(
            token0,
            token1,
            amountAReceived,
            amountBReceived,
            amountAMinAdd,
            amountBMinAdd,
            msg.sender,
            deadline
        );

        if (amountAReceived - amountASent > 0) {
            IERC20(token0).safeTransfer(
                msg.sender,
                amountAReceived - amountASent
            );
        }
        if (amountBReceived - amountBSent > 0) {
            IERC20(token1).safeTransfer(
                msg.sender,
                amountBReceived - amountBSent
            );
        }

        emit LPMigrated(lp, router, apeRouter, amount);
    }
}

File 19 of 20 : IApeSwapZap.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

/*
  ______                     ______                                 
 /      \                   /      \                                
|  β–“β–“β–“β–“β–“β–“\ ______   ______ |  β–“β–“β–“β–“β–“β–“\__   __   __  ______   ______  
| β–“β–“__| β–“β–“/      \ /      \| β–“β–“___\β–“β–“  \ |  \ |  \|      \ /      \ 
| β–“β–“    β–“β–“  β–“β–“β–“β–“β–“β–“\  β–“β–“β–“β–“β–“β–“\\β–“β–“    \| β–“β–“ | β–“β–“ | β–“β–“ \β–“β–“β–“β–“β–“β–“\  β–“β–“β–“β–“β–“β–“\
| β–“β–“β–“β–“β–“β–“β–“β–“ β–“β–“  | β–“β–“ β–“β–“    β–“β–“_\β–“β–“β–“β–“β–“β–“\ β–“β–“ | β–“β–“ | β–“β–“/      β–“β–“ β–“β–“  | β–“β–“
| β–“β–“  | β–“β–“ β–“β–“__/ β–“β–“ β–“β–“β–“β–“β–“β–“β–“β–“  \__| β–“β–“ β–“β–“_/ β–“β–“_/ β–“β–“  β–“β–“β–“β–“β–“β–“β–“ β–“β–“__/ β–“β–“
| β–“β–“  | β–“β–“ β–“β–“    β–“β–“\β–“β–“     \\β–“β–“    β–“β–“\β–“β–“   β–“β–“   β–“β–“\β–“β–“    β–“β–“ β–“β–“    β–“β–“
 \β–“β–“   \β–“β–“ β–“β–“β–“β–“β–“β–“β–“  \β–“β–“β–“β–“β–“β–“β–“ \β–“β–“β–“β–“β–“β–“  \β–“β–“β–“β–“β–“\β–“β–“β–“β–“  \β–“β–“β–“β–“β–“β–“β–“ β–“β–“β–“β–“β–“β–“β–“ 
         | β–“β–“                                             | β–“β–“      
         | β–“β–“                                             | β–“β–“      
          \β–“β–“                                              \β–“β–“         

 * App:             https://apeswap.finance
 * Medium:          https://ape-swap.medium.com
 * Twitter:         https://twitter.com/ape_swap
 * Discord:         https://discord.com/invite/apeswap
 * Telegram:        https://t.me/ape_swap
 * Announcements:   https://t.me/ape_swap_news
 * GitHub:          https://github.com/ApeSwapFinance
 */

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

interface IApeSwapZap {
    function zap(
        IERC20 _inputToken,
        uint256 _inputAmount,
        address[] memory _lpTokens, //[tokenA, tokenB]
        address[] calldata _path0,
        address[] calldata _path1,
        uint256[] memory _minAmountsSwap, //[A, B]
        uint256[] memory _minAmountsLP, //[amountAMin, amountBMin]
        address _to,
        uint256 _deadline
    ) external;

    function zapNative(
        address[] memory _lpTokens, //[tokenA, tokenB]
        address[] calldata _path0,
        address[] calldata _path1,
        uint256[] memory _minAmountsSwap, //[A, B]
        uint256[] memory _minAmountsLP, //[amountAMin, amountBMin]
        address _to,
        uint256 _deadline
    ) external payable;

    function getMinAmounts(
        uint256 _inputAmount,
        address[] calldata _path0,
        address[] calldata _path1
    )
        external
        view
        returns (
            uint256[2] memory _minAmountsSwap,
            uint256[2] memory _minAmountsLP
        );
}

File 20 of 20 : ApeSwapZap.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.15;

/*
  ______                     ______                                 
 /      \                   /      \                                
|  β–“β–“β–“β–“β–“β–“\ ______   ______ |  β–“β–“β–“β–“β–“β–“\__   __   __  ______   ______  
| β–“β–“__| β–“β–“/      \ /      \| β–“β–“___\β–“β–“  \ |  \ |  \|      \ /      \ 
| β–“β–“    β–“β–“  β–“β–“β–“β–“β–“β–“\  β–“β–“β–“β–“β–“β–“\\β–“β–“    \| β–“β–“ | β–“β–“ | β–“β–“ \β–“β–“β–“β–“β–“β–“\  β–“β–“β–“β–“β–“β–“\
| β–“β–“β–“β–“β–“β–“β–“β–“ β–“β–“  | β–“β–“ β–“β–“    β–“β–“_\β–“β–“β–“β–“β–“β–“\ β–“β–“ | β–“β–“ | β–“β–“/      β–“β–“ β–“β–“  | β–“β–“
| β–“β–“  | β–“β–“ β–“β–“__/ β–“β–“ β–“β–“β–“β–“β–“β–“β–“β–“  \__| β–“β–“ β–“β–“_/ β–“β–“_/ β–“β–“  β–“β–“β–“β–“β–“β–“β–“ β–“β–“__/ β–“β–“
| β–“β–“  | β–“β–“ β–“β–“    β–“β–“\β–“β–“     \\β–“β–“    β–“β–“\β–“β–“   β–“β–“   β–“β–“\β–“β–“    β–“β–“ β–“β–“    β–“β–“
 \β–“β–“   \β–“β–“ β–“β–“β–“β–“β–“β–“β–“  \β–“β–“β–“β–“β–“β–“β–“ \β–“β–“β–“β–“β–“β–“  \β–“β–“β–“β–“β–“\β–“β–“β–“β–“  \β–“β–“β–“β–“β–“β–“β–“ β–“β–“β–“β–“β–“β–“β–“ 
         | β–“β–“                                             | β–“β–“      
         | β–“β–“                                             | β–“β–“      
          \β–“β–“                                              \β–“β–“         

 * App:             https://apeswap.finance
 * Medium:          https://ape-swap.medium.com
 * Twitter:         https://twitter.com/ape_swap
 * Discord:         https://discord.com/invite/apeswap
 * Telegram:        https://t.me/ape_swap
 * Announcements:   https://t.me/ape_swap_news
 * GitHub:          https://github.com/ApeSwapFinance
 */

import "./IApeSwapZap.sol";
import "./lib/IApeRouter02.sol";
import "./lib/IApeFactory.sol";
import "./lib/IApePair.sol";
import "./lib/IWETH.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract ApeSwapZap is IApeSwapZap, ReentrancyGuard {
    using SafeERC20 for IERC20;

    struct BalanceLocalVars {
        uint256 amount0;
        uint256 amount1;
        uint256 balanceBefore;
    }

    IApeRouter02 public immutable router;
    IApeFactory public immutable factory;
    address public immutable WNATIVE;

    event Zap(address inputToken, uint256 inputAmount, address[] lpTokens);
    event ZapNative(uint256 inputAmount, address[] lpTokens);

    constructor(IApeRouter02 _router) {
        router = _router;
        factory = IApeFactory(router.factory());
        WNATIVE = router.WETH();
    }

    /// @dev The receive method is used as a fallback function in a contract
    /// and is called when ether is sent to a contract with no calldata.
    receive() external payable {
        require(
            msg.sender == WNATIVE,
            "ApeSwapZap: Only receive ether from wrapped"
        );
    }

    /// @notice Zap single token to LP
    /// @param inputToken Input token
    /// @param inputAmount Input amount
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param to address to receive LPs
    /// @param deadline Unix timestamp after which the transaction will revert
    function zap(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        address to,
        uint256 deadline
    ) external override nonReentrant {
        _zapInternal(
            inputToken,
            inputAmount,
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            to,
            deadline
        );
    }

    /// @notice Zap native token to LP
    /// @param lpTokens Tokens of LP to zap to
    /// @param path0 Path from input token to LP token0
    /// @param path1 Path from input token to LP token1
    /// @param minAmountsSwap The minimum amount of output tokens that must be received for swap
    /// @param minAmountsLP AmountAMin and amountBMin for adding liquidity
    /// @param to address to receive LPs
    /// @param deadline Unix timestamp after which the transaction will revert
    function zapNative(
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        address to,
        uint256 deadline
    ) external payable override nonReentrant {
        _zapNativeInternal(
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            to,
            deadline
        );
    }

    /// @notice get min amounts for swaps
    /// @param inputAmount total input amount for swap
    /// @param path0 path from input token to LP token0
    /// @param path1 path from input token to LP token1
    function getMinAmounts(
        uint256 inputAmount,
        address[] calldata path0,
        address[] calldata path1
    )
        external
        view
        override
        returns (
            uint256[2] memory minAmountsSwap,
            uint256[2] memory minAmountsLP
        )
    {
        require(
            path0.length >= 2 || path1.length >= 2,
            "ApeSwapZap: Needs at least one path"
        );

        uint256 inputAmountHalf = inputAmount / 2;

        uint256 minAmountSwap0 = inputAmountHalf;
        if (path0.length != 0) {
            uint256[] memory amountsOut0 = router.getAmountsOut(
                inputAmountHalf,
                path0
            );
            minAmountSwap0 = amountsOut0[amountsOut0.length - 1];
        }

        uint256 minAmountSwap1 = inputAmountHalf;
        if (path1.length != 0) {
            uint256[] memory amountsOut1 = router.getAmountsOut(
                inputAmountHalf,
                path1
            );
            minAmountSwap1 = amountsOut1[amountsOut1.length - 1];
        }

        address token0 = path0.length == 0 ? path1[0] : path0[path0.length - 1];
        address token1 = path1.length == 0 ? path0[0] : path1[path1.length - 1];

        IApePair lp = IApePair(factory.getPair(token0, token1));
        (uint256 reserveA, uint256 reserveB, ) = lp.getReserves();
        if (token0 == lp.token1()) {
            (reserveA, reserveB) = (reserveB, reserveA);
        }
        uint256 amountB = router.quote(minAmountSwap0, reserveA, reserveB);

        minAmountsSwap = [minAmountSwap0, minAmountSwap1];
        minAmountsLP = [minAmountSwap0, amountB];
    }

    function _zapInternal(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        address to,
        uint256 deadline
    ) internal {
        uint256 balanceBefore = _getBalance(inputToken);
        inputToken.safeTransferFrom(msg.sender, address(this), inputAmount);
        inputAmount = _getBalance(inputToken) - balanceBefore;

        _zapPrivate(
            inputToken,
            inputAmount,
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            to,
            deadline,
            false
        );
        emit Zap(address(inputToken), inputAmount, lpTokens);
    }

    function _zapNativeInternal(
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        address to,
        uint256 deadline
    ) internal {
        uint256 inputAmount = msg.value;
        IERC20 inputToken = IERC20(WNATIVE);
        IWETH(WNATIVE).deposit{ value: inputAmount }();

        _zapPrivate(
            inputToken,
            inputAmount,
            lpTokens,
            path0,
            path1,
            minAmountsSwap,
            minAmountsLP,
            to,
            deadline,
            true
        );
        emit ZapNative(inputAmount, lpTokens);
    }

    function _transfer(
        address token,
        uint256 amount,
        bool native
    ) internal {
        if (amount == 0) return;
        if (token == WNATIVE && native) {
            IWETH(WNATIVE).withdraw(amount);
            // 2600 COLD_ACCOUNT_ACCESS_COST plus 2300 transfer gas - 1
            // Intended to support transfers to contracts, but not allow for further code execution
            (bool success, ) = msg.sender.call{ value: amount, gas: 4899 }("");
            require(success, "native transfer error");
        } else {
            IERC20(token).safeTransfer(msg.sender, amount);
        }
    }

    function _getBalance(IERC20 token) internal view returns (uint256 balance) {
        balance = token.balanceOf(address(this));
    }

    function _zapPrivate(
        IERC20 inputToken,
        uint256 inputAmount,
        address[] memory lpTokens, //[tokenA, tokenB]
        address[] calldata path0,
        address[] calldata path1,
        uint256[] memory minAmountsSwap, //[A, B]
        uint256[] memory minAmountsLP, //[amountAMin, amountBMin]
        address to,
        uint256 deadline,
        bool native
    ) private {
        require(to != address(0), "ApeSwapZap: Can't zap to null address");
        require(
            lpTokens.length == 2,
            "ApeSwapZap: need exactly 2 tokens to form a LP"
        );
        require(
            factory.getPair(lpTokens[0], lpTokens[1]) != address(0),
            "ApeSwapZap: Pair doesn't exist"
        );

        BalanceLocalVars memory vars;

        inputToken.approve(address(router), inputAmount);

        vars.amount0 = inputAmount / 2;
        vars.balanceBefore = 0;
        if (lpTokens[0] != address(inputToken)) {
            require(
                path0[0] == address(inputToken),
                "ApeSwapZap: wrong path path0[0]"
            );
            require(
                path0[path0.length - 1] == lpTokens[0],
                "ApeSwapZap: wrong path path0[-1]"
            );
            vars.balanceBefore = _getBalance(IERC20(lpTokens[0]));
            router.swapExactTokensForTokens(
                vars.amount0,
                minAmountsSwap[0],
                path0,
                address(this),
                deadline
            );
            vars.amount0 =
                _getBalance(IERC20(lpTokens[0])) -
                vars.balanceBefore;
        }

        vars.amount1 = inputAmount / 2;
        if (lpTokens[1] != address(inputToken)) {
            require(
                path1[0] == address(inputToken),
                "ApeSwapZap: wrong path path1[0]"
            );
            require(
                path1[path1.length - 1] == lpTokens[1],
                "ApeSwapZap: wrong path path1[-1]"
            );
            vars.balanceBefore = _getBalance(IERC20(lpTokens[1]));
            router.swapExactTokensForTokens(
                vars.amount1,
                minAmountsSwap[1],
                path1,
                address(this),
                deadline
            );
            vars.amount1 =
                _getBalance(IERC20(lpTokens[1])) -
                vars.balanceBefore;
        }

        IERC20(lpTokens[0]).approve(address(router), vars.amount0);
        IERC20(lpTokens[1]).approve(address(router), vars.amount1);
        (uint256 amountA, uint256 amountB, ) = router.addLiquidity(
            lpTokens[0],
            lpTokens[1],
            vars.amount0,
            vars.amount1,
            minAmountsLP[0],
            minAmountsLP[1],
            to,
            deadline
        );

        if (lpTokens[0] == WNATIVE) {
            // Ensure WNATIVE is called last
            _transfer(lpTokens[1], vars.amount1 - amountB, native);
            _transfer(lpTokens[0], vars.amount0 - amountA, native);
        } else {
            _transfer(lpTokens[0], vars.amount0 - amountA, native);
            _transfer(lpTokens[1], vars.amount1 - amountB, native);
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IApeRouter02","name":"_router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IApePair","name":"lp","type":"address"},{"indexed":false,"internalType":"contract IApeRouter02","name":"fromRouter","type":"address"},{"indexed":false,"internalType":"contract IApeRouter02","name":"toRouter","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LPMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"lpTokens","type":"address[]"}],"name":"Zap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"ZapLPPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"ZapLPPoolNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"ZapMiniApeV2","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"ZapMiniApeV2Native","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"lpTokens","type":"address[]"}],"name":"ZapNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"ZapSingleAssetPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"ZapSingleAssetPoolNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract ICustomBill","name":"bill","type":"address"}],"name":"ZapTBill","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract ICustomBill","name":"bill","type":"address"}],"name":"ZapTBillNative","type":"event"},{"inputs":[],"name":"WNATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apeRouter","outputs":[{"internalType":"contract IApeRouter02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IApeFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"}],"name":"getMinAmounts","outputs":[{"internalType":"uint256[2]","name":"minAmountsSwap","type":"uint256[2]"},{"internalType":"uint256[2]","name":"minAmountsLP","type":"uint256[2]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IApeRouter02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"zap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IApeRouter02","name":"router","type":"address"},{"internalType":"contract IApePair","name":"lp","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountAMinRemove","type":"uint256"},{"internalType":"uint256","name":"amountBMinRemove","type":"uint256"},{"internalType":"uint256","name":"amountAMinAdd","type":"uint256"},{"internalType":"uint256","name":"amountBMinAdd","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"zapLPMigrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"zapLPPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"zapLPPoolNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract IMiniApeV2","name":"miniApe","type":"address"},{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"zapMiniApeV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract IMiniApeV2","name":"miniApe","type":"address"},{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"zapMiniApeV2Native","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"zapNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"minAmountsSwap","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"zapSingleAssetPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"minAmountsSwap","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract IBEP20RewardApeV5","name":"pool","type":"address"}],"name":"zapSingleAssetPoolNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract ICustomBill","name":"bill","type":"address"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"zapTBill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"address[]","name":"path0","type":"address[]"},{"internalType":"address[]","name":"path1","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsSwap","type":"uint256[]"},{"internalType":"uint256[]","name":"minAmountsLP","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"contract ICustomBill","name":"bill","type":"address"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"zapTBillNative","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b506040516200573538038062005735833981016040819052620000359162000168565b60016000556001600160a01b03811660808190526040805163c45a015560e01b8152905183928392909163c45a0155916004808201926020929091908290030181865afa1580156200008b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b1919062000168565b6001600160a01b031660a0816001600160a01b0316815250506080516001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200010b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000131919062000168565b6001600160a01b0390811660c0529190911660e052506200018f9050565b6001600160a01b03811681146200016557600080fd5b50565b6000602082840312156200017b57600080fd5b815162000188816200014f565b9392505050565b60805160a05160c05160e0516154c4620002716000396000818161025f01528181612d4001528181612dd201528181612e450152612f6d015260008181610107015281816102de0152818161040b01528181613585015281816135a8015281816140d5015281816142ab015261430201526000818161033801528181611e3201526137720152600081816103ac01528181611bc001528181611c8c01528181611fbe0152818161317901528181613201015281816138d301528181613b0701528181613d7901528181613e8901528181613f390152613fc301526154c46000f3fe6080604052600436106100f75760003560e01c8063a449ef081161008a578063c45a015511610059578063c45a015514610326578063cdf8bec51461035a578063dcb0536e1461037a578063f887ea401461039a57600080fd5b8063a449ef081461029e578063b381cf40146102cc578063bf2ac34314610300578063bfbab40b1461031357600080fd5b80637486f330116100c65780637486f3301461020757806376280036146102275780637f51cf8b1461023a57806392f687781461024d57600080fd5b80632843dddf1461019457806335fea448146101a757806365946a3b146101c757806369a257e8146101e757600080fd5b3661018f57336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461018d5760405162461bcd60e51b815260206004820152602b60248201527f417065537761705a61703a204f6e6c792072656365697665206574686572206660448201526a1c9bdb481ddc985c1c195960aa1b60648201526084015b60405180910390fd5b005b600080fd5b61018d6101a2366004614623565b6103ce565b3480156101b357600080fd5b5061018d6101c23660046147c5565b6104d1565b3480156101d357600080fd5b5061018d6101e2366004614900565b610a50565b3480156101f357600080fd5b5061018d610202366004614a18565b610f85565b34801561021357600080fd5b5061018d610222366004614a9e565b61104c565b61018d610235366004614bb6565b611098565b61018d610248366004614bb6565b6115ce565b34801561025957600080fd5b506102817f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102aa57600080fd5b506102be6102b9366004614cb6565b611b17565b604051610295929190614d52565b3480156102d857600080fd5b506102817f000000000000000000000000000000000000000000000000000000000000000081565b61018d61030e366004614d6d565b61206b565b61018d610321366004614e62565b6120b3565b34801561033257600080fd5b506102817f000000000000000000000000000000000000000000000000000000000000000081565b34801561036657600080fd5b5061018d6103753660046147c5565b6125cc565b34801561038657600080fd5b5061018d610395366004614f57565b612b00565b3480156103a657600080fd5b506102817f000000000000000000000000000000000000000000000000000000000000000081565b6002600054036103f05760405162461bcd60e51b815260040161018490614fc2565b6002600090815560408051630d0e30db60e41b8152905134927f0000000000000000000000000000000000000000000000000000000000000000926001600160a01b0384169263d0e30db09286926004808201939182900301818588803b15801561045a57600080fd5b505af115801561046e573d6000803e3d6000fd5b505050505061048281838989898989612fc2565b604080518381526001600160a01b03851660208201527f0864d9de329ff01fb0e285c707907ad33167daca48ee5c1c7c4edc5ebd553e78910160405180910390a1505060016000555050505050565b6002600054036104f35760405162461bcd60e51b815260040161018490614fc2565b600260009081556040516378ed5d1f60e01b8152600481018390526001600160a01b038416906378ed5d1f906024016020604051808303816000875af1158015610541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105659190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c99190614ff9565b6001600160a01b03168b6000815181106105e5576105e5615016565b60200260200101516001600160a01b031614801561068f5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106609190614ff9565b6001600160a01b03168b60018151811061067c5761067c615016565b60200260200101516001600160a01b0316145b806107bd5750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f79190614ff9565b6001600160a01b03168b60018151811061071357610713615016565b60200260200101516001600160a01b03161480156107bd5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561076a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078e9190614ff9565b6001600160a01b03168b6000815181106107aa576107aa615016565b60200260200101516001600160a01b0316145b6108175760405162461bcd60e51b815260206004820152602560248201527f417065537761705a61703a2057726f6e67204c50207061697220666f72204d696044820152646e6941706560d81b6064820152608401610184565b61082a8d8d8d8d8d8d8d8d8d308e613404565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610871573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610895919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906108c69087908590600401615045565b6020604051808303816000875af11580156108e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610909919061505e565b50604051638dbdbe6d60e01b815260048101849052602481018290523360448201526001600160a01b03851690638dbdbe6d90606401600060405180830381600087803b15801561095957600080fd5b505af115801561096d573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b391506109a0908790600090600401615045565b6020604051808303816000875af11580156109bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e3919061505e565b507ff1ee85beaab4e417aa82356a1987f34c8a4d209194bc93a445b4dbf570c880938e8e85604051610a33939291906001600160a01b039390931683526020830191909152604082015260600190565b60405180910390a150506001600055505050505050505050505050565b600260005403610a725760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000816001600160a01b0316631c39b6726040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade9190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b429190614ff9565b6001600160a01b03168a600081518110610b5e57610b5e615016565b60200260200101516001600160a01b0316148015610c085750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd99190614ff9565b6001600160a01b03168a600181518110610bf557610bf5615016565b60200260200101516001600160a01b0316145b80610d365750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c709190614ff9565b6001600160a01b03168a600181518110610c8c57610c8c615016565b60200260200101516001600160a01b0316148015610d365750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d079190614ff9565b6001600160a01b03168a600081518110610d2357610d23615016565b60200260200101516001600160a01b0316145b610d525760405162461bcd60e51b815260040161018490615080565b610d658c8c8c8c8c8c8c8c8c308d613404565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610dac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd0919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b390610e019086908590600401615045565b6020604051808303816000875af1158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e44919061505e565b506040516370aff70f60e01b8152600481018290523360248201526001600160a01b038416906370aff70f90604401600060405180830381600087803b158015610e8d57600080fd5b505af1158015610ea1573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b39150610ed4908690600090600401615045565b6020604051808303816000875af1158015610ef3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f17919061505e565b507f7d3698d30ac93ff91cb00b4e12cadd07e613ef452b72a2f503e27d066a58856e8d8d85604051610f69939291906001600160a01b0393841681526020810192909252909116604082015260600190565b60405180910390a1505060016000555050505050505050505050565b600260005403610fa75760405162461bcd60e51b815260040161018490614fc2565b60026000908155610fb78861349a565b9050610fce6001600160a01b03891633308a61350b565b80610fd88961349a565b610fe291906150c2565b9650610ff388888888888888612fc2565b604080516001600160a01b038a81168252602082018a905284168183015290517f7b69944e54cb50e622cc9c3d1091a7ab275297c06c997ea6ef7a56ce58d878159181900360600190a150506001600055505050505050565b60026000540361106e5760405162461bcd60e51b815260040161018490614fc2565b60026000556110868b8b8b8b8b8b8b8b8b8b8b613404565b50506001600055505050505050505050565b6002600054036110ba5760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000826001600160a01b031663dbc162de6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111289190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611168573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118c9190614ff9565b6001600160a01b03168b6000815181106111a8576111a8615016565b60200260200101516001600160a01b03161480156112525750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112239190614ff9565b6001600160a01b03168b60018151811061123f5761123f615016565b60200260200101516001600160a01b0316145b806113805750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190614ff9565b6001600160a01b03168b6001815181106112d6576112d6615016565b60200260200101516001600160a01b03161480156113805750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561132d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113519190614ff9565b6001600160a01b03168b60008151811061136d5761136d615016565b60200260200101516001600160a01b0316145b61139c5760405162461bcd60e51b8152600401610184906150e7565b6113ad8b8b8b8b8b8b8b308c61357c565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156113f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611418919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906114499087908590600401615045565b6020604051808303816000875af1158015611468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148c919061505e565b50604051638dbdbe6d60e01b815260048101829052602481018490523360448201526001600160a01b03851690638dbdbe6d906064016020604051808303816000875af11580156114e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611505919061502c565b5060405163095ea7b360e01b81526001600160a01b0383169063095ea7b390611535908790600090600401615045565b6020604051808303816000875af1158015611554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611578919061505e565b50604080513481526001600160a01b03861660208201527fbba058d4778dd4dfe5b28e159c111e8a68aefcb03e525413f08586f1ab6770d191015b60405180910390a15050600160005550505050505050505050565b6002600054036115f05760405162461bcd60e51b815260040161018490614fc2565b600260009081556040516378ed5d1f60e01b8152600481018390526001600160a01b038416906378ed5d1f906024016020604051808303816000875af115801561163e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116629190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c69190614ff9565b6001600160a01b03168b6000815181106116e2576116e2615016565b60200260200101516001600160a01b031614801561178c5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611739573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175d9190614ff9565b6001600160a01b03168b60018151811061177957611779615016565b60200260200101516001600160a01b0316145b806118ba5750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f49190614ff9565b6001600160a01b03168b60018151811061181057611810615016565b60200260200101516001600160a01b03161480156118ba5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b9190614ff9565b6001600160a01b03168b6000815181106118a7576118a7615016565b60200260200101516001600160a01b0316145b6119165760405162461bcd60e51b815260206004820152602760248201527f417065537761705a61703a2057726f6e67204c50207061697220666f72204475604482015266616c204661726d60c81b6064820152608401610184565b6119278b8b8b8b8b8b8b308c61357c565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561196e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611992919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906119c39087908590600401615045565b6020604051808303816000875af11580156119e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a06919061505e565b50604051638dbdbe6d60e01b815260048101849052602481018290523360448201526001600160a01b03851690638dbdbe6d90606401600060405180830381600087803b158015611a5657600080fd5b505af1158015611a6a573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b39150611a9d908790600090600401615045565b6020604051808303816000875af1158015611abc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae0919061505e565b5060408051348152602081018590527fe7eb221216ecf3b8c976ba85c999fddecc26f0f4ecb57451371f6ad6111994fe91016115b3565b611b1f614592565b611b27614592565b600285101580611b38575060028310155b611b905760405162461bcd60e51b815260206004820152602360248201527f417065537761705a61703a204e65656473206174206c65617374206f6e6520706044820152620c2e8d60eb1b6064820152608401610184565b6000611b9d60028961512a565b9050808615611c6b5760405163d06ca61f60e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d06ca61f90611bf99086908d908d90600401615195565b600060405180830381865afa158015611c16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c3e91908101906151b8565b90508060018251611c4f91906150c2565b81518110611c5f57611c5f615016565b60200260200101519150505b818515611d375760405163d06ca61f60e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d06ca61f90611cc59087908c908c90600401615195565b600060405180830381865afa158015611ce2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d0a91908101906151b8565b90508060018251611d1b91906150c2565b81518110611d2b57611d2b615016565b60200260200101519150505b60008815611d75578989611d4c6001826150c2565b818110611d5b57611d5b615016565b9050602002016020810190611d70919061523d565b611d9d565b87876000818110611d8857611d88615016565b9050602002016020810190611d9d919061523d565b905060008715611ddd578888611db46001826150c2565b818110611dc357611dc3615016565b9050602002016020810190611dd8919061523d565b611e05565b8a8a6000818110611df057611df0615016565b9050602002016020810190611e05919061523d565b60405163e6a4390560e01b81526001600160a01b03848116600483015280831660248301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063e6a4390590604401602060405180830381865afa158015611e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9d9190614ff9565b9050600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611ee0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f049190615271565b506001600160701b031691506001600160701b03169150826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7d9190614ff9565b6001600160a01b0316856001600160a01b031603611f9757905b604051632b58577b60e21b81526004810188905260248101839052604481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ad615dec90606401602060405180830381865afa15801561200d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612031919061502c565b6040805180820182528a815260208082019a909a5281518083019092529981529788015250959e949d50939b505050505050505050505050565b60026000540361208d5760405162461bcd60e51b815260040161018490614fc2565b60026000556120a389898989898989898961357c565b5050600160005550505050505050565b6002600054036120d55760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000816001600160a01b0316631c39b6726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561211d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121419190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612181573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a59190614ff9565b6001600160a01b03168a6000815181106121c1576121c1615016565b60200260200101516001600160a01b031614801561226b5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223c9190614ff9565b6001600160a01b03168a60018151811061225857612258615016565b60200260200101516001600160a01b0316145b806123995750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d39190614ff9565b6001600160a01b03168a6001815181106122ef576122ef615016565b60200260200101516001600160a01b03161480156123995750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236a9190614ff9565b6001600160a01b03168a60008151811061238657612386615016565b60200260200101516001600160a01b0316145b6123b55760405162461bcd60e51b815260040161018490615080565b6123c68a8a8a8a8a8a8a308b61357c565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561240d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612431919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906124629086908590600401615045565b6020604051808303816000875af1158015612481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a5919061505e565b506040516370aff70f60e01b8152600481018290523360248201526001600160a01b038416906370aff70f90604401600060405180830381600087803b1580156124ee57600080fd5b505af1158015612502573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b39150612535908690600090600401615045565b6020604051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061505e565b50604080513481526001600160a01b03851660208201527f0508054cbbbec64f9a98657481af938dae1891415b0863ccc3402ac1382577a5910160405180910390a150506001600055505050505050505050565b6002600054036125ee5760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000826001600160a01b031663dbc162de6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612638573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265c9190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c09190614ff9565b6001600160a01b03168b6000815181106126dc576126dc615016565b60200260200101516001600160a01b03161480156127865750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612733573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127579190614ff9565b6001600160a01b03168b60018151811061277357612773615016565b60200260200101516001600160a01b0316145b806128b45750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ee9190614ff9565b6001600160a01b03168b60018151811061280a5761280a615016565b60200260200101516001600160a01b03161480156128b45750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128859190614ff9565b6001600160a01b03168b6000815181106128a1576128a1615016565b60200260200101516001600160a01b0316145b6128d05760405162461bcd60e51b8152600401610184906150e7565b6128e38d8d8d8d8d8d8d8d8d308e613404565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561292a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294e919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b39061297f9087908590600401615045565b6020604051808303816000875af115801561299e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c2919061505e565b50604051638dbdbe6d60e01b815260048101829052602481018490523360448201526001600160a01b03851690638dbdbe6d906064016020604051808303816000875af1158015612a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3b919061502c565b5060405163095ea7b360e01b81526001600160a01b0383169063095ea7b390612a6b908790600090600401615045565b6020604051808303816000875af1158015612a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aae919061505e565b507f452471abcb188a45e0b1afd12999cf4df9ed51c4b01cf813bbbdabaa9b382cad8e8e86604051610a33939291906001600160a01b0393841681526020810192909252909116604082015260600190565b600260005403612b225760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000876001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8e9190614ff9565b90506000886001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf49190614ff9565b9050612c0b6001600160a01b038a1633308b61350b565b60405163095ea7b360e01b81526001600160a01b038a169063095ea7b390612c39908d908c90600401615045565b6020604051808303816000875af1158015612c58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7c919061505e565b50604051635d5155ef60e11b81526001600160a01b0383811660048301528281166024830152604482018a905260648201899052608482018890523060a483015260c4820185905260009182918d169063baa2abde9060e40160408051808303816000875af1158015612cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1791906152c1565b60405163095ea7b360e01b815291935091506001600160a01b0385169063095ea7b390612d6a907f0000000000000000000000000000000000000000000000000000000000000000908690600401615045565b6020604051808303816000875af1158015612d89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dad919061505e565b5060405163095ea7b360e01b81526001600160a01b0384169063095ea7b390612dfc907f0000000000000000000000000000000000000000000000000000000000000000908590600401615045565b6020604051808303816000875af1158015612e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e3f919061505e565b506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e8e33700878787878e8e338f6040518963ffffffff1660e01b8152600401612e9d9897969594939291906152e5565b6060604051808303816000875af1158015612ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee0919061532e565b5090925090506000612ef283866150c2565b1115612f1757612f1733612f0684876150c2565b6001600160a01b0389169190613675565b6000612f2382856150c2565b1115612f4857612f4833612f3783866150c2565b6001600160a01b0388169190613675565b7fbef8fc428932b971d2badb42f83b58752429ad4733367b71f4bddbd2023b99f88d8f7f00000000000000000000000000000000000000000000000000000000000000008f604051610a3394939291906001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6000816001600160a01b0316631c39b6726040518163ffffffff1660e01b8152600401602060405180830381865afa158015613002573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130269190614ff9565b9050866001600160a01b03898116908316146132b457886001600160a01b03168787600081811061305957613059615016565b905060200201602081019061306e919061523d565b6001600160a01b0316146130c45760405162461bcd60e51b815260206004820152601e60248201527f417065537761705a61703a2077726f6e67207061746820706174685b305d00006044820152606401610184565b6001600160a01b03821687876130db6001826150c2565b8181106130ea576130ea615016565b90506020020160208101906130ff919061523d565b6001600160a01b0316146131555760405162461bcd60e51b815260206004820152601f60248201527f417065537761705a61703a2077726f6e67207061746820706174685b2d315d006044820152606401610184565b60405163095ea7b360e01b81526001600160a01b038a169063095ea7b3906131a3907f0000000000000000000000000000000000000000000000000000000000000000908c90600401615045565b6020604051808303816000875af11580156131c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e6919061505e565b506040516338ed173960e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906338ed173990613240908c908a908d908d9030908d9060040161535c565b6000604051808303816000875af115801561325f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261328791908101906151b8565b9050806001825161329891906150c2565b815181106132a8576132a8615016565b60200260200101519150505b60405163095ea7b360e01b81526001600160a01b0383169063095ea7b3906132e29086908590600401615045565b6020604051808303816000875af1158015613301573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613325919061505e565b506040516370aff70f60e01b8152600481018290523360248201526001600160a01b038416906370aff70f90604401600060405180830381600087803b15801561336e57600080fd5b505af1158015613382573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b391506133b5908690600090600401615045565b6020604051808303816000875af11580156133d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f8919061505e565b50505050505050505050565b600061340f8c61349a565b90506134266001600160a01b038d1633308e61350b565b806134308d61349a565b61343a91906150c2565b9a506134518c8c8c8c8c8c8c8c8c8c8c6000613699565b7f1fd2bf03b44ce5cb29193cc54927f3fae3203d6bee3b52fa2b41b0ae38d9dd7d8c8c8c604051613484939291906153d3565b60405180910390a1505050505050505050505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156134e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613505919061502c565b92915050565b6040516001600160a01b03808516602483015283166044820152606481018290526135769085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526141ca565b50505050565b600034905060007f000000000000000000000000000000000000000000000000000000000000000090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561360157600080fd5b505af1158015613615573d6000803e3d6000fd5b505050505061362f81838d8d8d8d8d8d8d8d8d6001613699565b7f2e4eeaaef6f24db22c68d3447461155fb43767e27eefa5655f863218ab23aa04828c6040516136609291906153fa565b60405180910390a15050505050505050505050565b6136948363a9059cbb60e01b848460405160240161353f929190615045565b505050565b6001600160a01b0383166136fd5760405162461bcd60e51b815260206004820152602560248201527f417065537761705a61703a2043616e2774207a617020746f206e756c6c206164604482015264647265737360d81b6064820152608401610184565b89516002146137655760405162461bcd60e51b815260206004820152602e60248201527f417065537761705a61703a206e6565642065786163746c79203220746f6b656e60448201526d07320746f20666f726d2061204c560941b6064820152608401610184565b60006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058c6000815181106137b2576137b2615016565b60200260200101518d6001815181106137cd576137cd615016565b60200260200101516040518363ffffffff1660e01b81526004016138079291906001600160a01b0392831681529116602082015260400190565b602060405180830381865afa158015613824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138489190614ff9565b6001600160a01b03160361389e5760405162461bcd60e51b815260206004820152601e60248201527f417065537761705a61703a205061697220646f65736e277420657869737400006044820152606401610184565b6138c260405180606001604052806000815260200160008152602001600081525090565b8c6001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008e6040518363ffffffff1660e01b8152600401613910929190615045565b6020604051808303816000875af115801561392f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613953919061505e565b5061395f60028d61512a565b81526000604082018190528b516001600160a01b038f16918d9161398557613985615016565b60200260200101516001600160a01b031614613bdc578c6001600160a01b03168a8a60008181106139b8576139b8615016565b90506020020160208101906139cd919061523d565b6001600160a01b031614613a235760405162461bcd60e51b815260206004820152601f60248201527f417065537761705a61703a2077726f6e6720706174682070617468305b305d006044820152606401610184565b8a600081518110613a3657613a36615016565b60209081029190910101516001600160a01b03168a8a613a576001826150c2565b818110613a6657613a66615016565b9050602002016020810190613a7b919061523d565b6001600160a01b031614613ad15760405162461bcd60e51b815260206004820181905260248201527f417065537761705a61703a2077726f6e6720706174682070617468305b2d315d6044820152606401610184565b613af48b600081518110613ae757613ae7615016565b602002602001015161349a565b6040820152805186516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916338ed1739918990600090613b3f57613b3f615016565b60200260200101518d8d30896040518763ffffffff1660e01b8152600401613b6c9695949392919061535c565b6000604051808303816000875af1158015613b8b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613bb391908101906151b8565b508060400151613bcf8c600081518110613ae757613ae7615016565b613bd991906150c2565b81525b613be760028d61512a565b60208201528a516001600160a01b038e16908c906001908110613c0c57613c0c615016565b60200260200101516001600160a01b031614613e5e578c6001600160a01b031688886000818110613c3f57613c3f615016565b9050602002016020810190613c54919061523d565b6001600160a01b031614613caa5760405162461bcd60e51b815260206004820152601f60248201527f417065537761705a61703a2077726f6e6720706174682070617468315b305d006044820152606401610184565b8a600181518110613cbd57613cbd615016565b60209081029190910101516001600160a01b03168888613cde6001826150c2565b818110613ced57613ced615016565b9050602002016020810190613d02919061523d565b6001600160a01b031614613d585760405162461bcd60e51b815260206004820181905260248201527f417065537761705a61703a2077726f6e6720706174682070617468315b2d315d6044820152606401610184565b613d6e8b600181518110613ae757613ae7615016565b8160400181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166338ed1739826020015188600181518110613dbe57613dbe615016565b60200260200101518b8b30896040518763ffffffff1660e01b8152600401613deb9695949392919061535c565b6000604051808303816000875af1158015613e0a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e3291908101906151b8565b508060400151613e4e8c600181518110613ae757613ae7615016565b613e5891906150c2565b60208201525b8a600081518110613e7157613e71615016565b60200260200101516001600160a01b031663095ea7b37f000000000000000000000000000000000000000000000000000000000000000083600001516040518363ffffffff1660e01b8152600401613eca929190615045565b6020604051808303816000875af1158015613ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f0d919061505e565b508a600181518110613f2157613f21615016565b60200260200101516001600160a01b031663095ea7b37f000000000000000000000000000000000000000000000000000000000000000083602001516040518363ffffffff1660e01b8152600401613f7a929190615045565b6020604051808303816000875af1158015613f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbd919061505e565b506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e8e337008e60008151811061400357614003615016565b60200260200101518f60018151811061401e5761401e615016565b6020026020010151866000015187602001518c60008151811061404357614043615016565b60200260200101518d60018151811061405e5761405e615016565b60200260200101518d8d6040518963ffffffff1660e01b815260040161408b9897969594939291906152e5565b6060604051808303816000875af11580156140aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140ce919061532e565b50915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168d60008151811061411057614110615016565b60200260200101516001600160a01b03160361418d5761415a8d60018151811061413c5761413c615016565b602002602001015182856020015161415491906150c2565b8661429c565b6141888d60008151811061417057614170615016565b602002602001015183856000015161415491906150c2565b6141b9565b6141a38d60008151811061417057614170615016565b6141b98d60018151811061413c5761413c615016565b505050505050505050505050505050565b600061421f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661440f9092919063ffffffff16565b805190915015613694578080602001905181019061423d919061505e565b6136945760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610184565b816000036142a957505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161480156142e75750805b156143fb57604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561434e57600080fd5b505af1158015614362573d6000803e3d6000fd5b50506040516000925033915061132390859084818181858888f193505050503d80600081146143ad576040519150601f19603f3d011682016040523d82523d6000602084013e6143b2565b606091505b50509050806135765760405162461bcd60e51b81526020600482015260156024820152743730ba34bb32903a3930b739b332b91032b93937b960591b6044820152606401610184565b6136946001600160a01b0384163384613675565b606061441e8484600085614428565b90505b9392505050565b6060824710156144895760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610184565b6001600160a01b0385163b6144e05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610184565b600080866001600160a01b031685876040516144fc919061543f565b60006040518083038185875af1925050503d8060008114614539576040519150601f19603f3d011682016040523d82523d6000602084013e61453e565b606091505b509150915061454e828286614559565b979650505050505050565b60608315614568575081614421565b8251156145785782518084602001fd5b8160405162461bcd60e51b8152600401610184919061545b565b60405180604001604052806002906020820280368337509192915050565b60008083601f8401126145c257600080fd5b5081356001600160401b038111156145d957600080fd5b6020830191508360208260051b85010111156145f457600080fd5b9250929050565b6001600160a01b038116811461461057600080fd5b50565b803561461e816145fb565b919050565b60008060008060006080868803121561463b57600080fd5b85356001600160401b0381111561465157600080fd5b61465d888289016145b0565b9096509450506020860135925060408601359150606086013561467f816145fb565b809150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156146cb576146cb61468d565b604052919050565b60006001600160401b038211156146ec576146ec61468d565b5060051b60200190565b600082601f83011261470757600080fd5b8135602061471c614717836146d3565b6146a3565b82815260059290921b8401810191818101908684111561473b57600080fd5b8286015b8481101561475f578035614752816145fb565b835291830191830161473f565b509695505050505050565b600082601f83011261477b57600080fd5b8135602061478b614717836146d3565b82815260059290921b840181019181810190868411156147aa57600080fd5b8286015b8481101561475f57803583529183019183016147ae565b6000806000806000806000806000806000806101408d8f0312156147e857600080fd5b6147f18d614613565b9b5060208d01359a506001600160401b0360408e0135111561481257600080fd5b6148228e60408f01358f016146f6565b99506001600160401b0360608e0135111561483c57600080fd5b61484c8e60608f01358f016145b0565b90995097506001600160401b0360808e0135111561486957600080fd5b6148798e60808f01358f016145b0565b90975095506001600160401b0360a08e0135111561489657600080fd5b6148a68e60a08f01358f0161476a565b94506001600160401b0360c08e013511156148c057600080fd5b6148d08e60c08f01358f0161476a565b935060e08d013592506148e66101008e01614613565b91506101208d013590509295989b509295989b509295989b565b60008060008060008060008060008060006101208c8e03121561492257600080fd5b61492b8c614613565b9a5060208c013599506001600160401b038060408e0135111561494d57600080fd5b61495d8e60408f01358f016146f6565b99508060608e0135111561497057600080fd5b6149808e60608f01358f016145b0565b909950975060808d013581101561499657600080fd5b6149a68e60808f01358f016145b0565b909750955060a08d01358110156149bc57600080fd5b6149cc8e60a08f01358f0161476a565b94508060c08e013511156149df57600080fd5b506149f08d60c08e01358e0161476a565b925060e08c01359150614a066101008d01614613565b90509295989b509295989b9093969950565b600080600080600080600060c0888a031215614a3357600080fd5b8735614a3e816145fb565b96506020880135955060408801356001600160401b03811115614a6057600080fd5b614a6c8a828b016145b0565b909650945050606088013592506080880135915060a0880135614a8e816145fb565b8091505092959891949750929550565b60008060008060008060008060008060006101208c8e031215614ac057600080fd5b614ac98c614613565b9a5060208c013599506001600160401b038060408e01351115614aeb57600080fd5b614afb8e60408f01358f016146f6565b99508060608e01351115614b0e57600080fd5b614b1e8e60608f01358f016145b0565b909950975060808d0135811015614b3457600080fd5b614b448e60808f01358f016145b0565b909750955060a08d0135811015614b5a57600080fd5b614b6a8e60a08f01358f0161476a565b94508060c08e01351115614b7d57600080fd5b50614b8e8d60c08e01358e0161476a565b9250614b9c60e08d01614613565b91506101008c013590509295989b509295989b9093969950565b6000806000806000806000806000806101008b8d031215614bd657600080fd5b8a356001600160401b0380821115614bed57600080fd5b614bf98e838f016146f6565b9b5060208d0135915080821115614c0f57600080fd5b614c1b8e838f016145b0565b909b50995060408d0135915080821115614c3457600080fd5b614c408e838f016145b0565b909950975060608d0135915080821115614c5957600080fd5b614c658e838f0161476a565b965060808d0135915080821115614c7b57600080fd5b50614c888d828e0161476a565b94505060a08b01359250614c9e60c08c01614613565b915060e08b013590509295989b9194979a5092959850565b600080600080600060608688031215614cce57600080fd5b8535945060208601356001600160401b0380821115614cec57600080fd5b614cf889838a016145b0565b90965094506040880135915080821115614d1157600080fd5b50614d1e888289016145b0565b969995985093965092949392505050565b8060005b6002811015613576578151845260209384019390910190600101614d33565b60808101614d608285614d2f565b6144216040830184614d2f565b600080600080600080600080600060e08a8c031215614d8b57600080fd5b89356001600160401b0380821115614da257600080fd5b614dae8d838e016146f6565b9a5060208c0135915080821115614dc457600080fd5b614dd08d838e016145b0565b909a50985060408c0135915080821115614de957600080fd5b614df58d838e016145b0565b909850965060608c0135915080821115614e0e57600080fd5b614e1a8d838e0161476a565b955060808c0135915080821115614e3057600080fd5b50614e3d8c828d0161476a565b935050614e4c60a08b01614613565b915060c08a013590509295985092959850929598565b600080600080600080600080600060e08a8c031215614e8057600080fd5b89356001600160401b0380821115614e9757600080fd5b614ea38d838e016146f6565b9a5060208c0135915080821115614eb957600080fd5b614ec58d838e016145b0565b909a50985060408c0135915080821115614ede57600080fd5b614eea8d838e016145b0565b909850965060608c0135915080821115614f0357600080fd5b614f0f8d838e0161476a565b955060808c0135915080821115614f2557600080fd5b50614f328c828d0161476a565b93505060a08a01359150614f4860c08b01614613565b90509295985092959850929598565b600080600080600080600080610100898b031215614f7457600080fd5b8835614f7f816145fb565b97506020890135614f8f816145fb565b979a9799505050506040860135956060810135956080820135955060a0820135945060c0820135935060e0909101359150565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561500b57600080fd5b8151614421816145fb565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561503e57600080fd5b5051919050565b6001600160a01b03929092168252602082015260400190565b60006020828403121561507057600080fd5b8151801515811461442157600080fd5b60208082526022908201527f417065537761705a61703a2057726f6e67204c50207061697220666f7220506f6040820152611bdb60f21b606082015260800190565b6000828210156150e257634e487b7160e01b600052601160045260246000fd5b500390565b60208082526023908201527f417065537761705a61703a2057726f6e67204c50207061697220666f722054426040820152621a5b1b60ea1b606082015260800190565b60008261514757634e487b7160e01b600052601260045260246000fd5b500490565b8183526000602080850194508260005b8581101561518a57813561516f816145fb565b6001600160a01b03168752958201959082019060010161515c565b509495945050505050565b8381526040602082015260006151af60408301848661514c565b95945050505050565b600060208083850312156151cb57600080fd5b82516001600160401b038111156151e157600080fd5b8301601f810185136151f257600080fd5b8051615200614717826146d3565b81815260059190911b8201830190838101908783111561521f57600080fd5b928401925b8284101561454e57835182529284019290840190615224565b60006020828403121561524f57600080fd5b8135614421816145fb565b80516001600160701b038116811461461e57600080fd5b60008060006060848603121561528657600080fd5b61528f8461525a565b925061529d6020850161525a565b9150604084015163ffffffff811681146152b657600080fd5b809150509250925092565b600080604083850312156152d457600080fd5b505080516020909101519092909150565b6001600160a01b039889168152968816602088015260408701959095526060860193909352608085019190915260a084015290921660c082015260e08101919091526101000190565b60008060006060848603121561534357600080fd5b8351925060208401519150604084015190509250925092565b86815285602082015260a06040820152600061537c60a08301868861514c565b6001600160a01b039490941660608301525060800152949350505050565b600081518084526020808501945080840160005b8381101561518a5781516001600160a01b0316875295820195908201906001016153ae565b60018060a01b03841681528260208201526060604082015260006151af606083018461539a565b82815260406020820152600061441e604083018461539a565b60005b8381101561542e578181015183820152602001615416565b838111156135765750506000910152565b60008251615451818460208701615413565b9190910192915050565b602081526000825180602084015261547a816040850160208701615413565b601f01601f1916919091016040019291505056fea2646970667358221220b46a0a8722f6adc5357af1f5e8adb776f4bc252f2183d4828cfa5511591c647064736f6c634300080f0033000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607

Deployed Bytecode

0x6080604052600436106100f75760003560e01c8063a449ef081161008a578063c45a015511610059578063c45a015514610326578063cdf8bec51461035a578063dcb0536e1461037a578063f887ea401461039a57600080fd5b8063a449ef081461029e578063b381cf40146102cc578063bf2ac34314610300578063bfbab40b1461031357600080fd5b80637486f330116100c65780637486f3301461020757806376280036146102275780637f51cf8b1461023a57806392f687781461024d57600080fd5b80632843dddf1461019457806335fea448146101a757806365946a3b146101c757806369a257e8146101e757600080fd5b3661018f57336001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270161461018d5760405162461bcd60e51b815260206004820152602b60248201527f417065537761705a61703a204f6e6c792072656365697665206574686572206660448201526a1c9bdb481ddc985c1c195960aa1b60648201526084015b60405180910390fd5b005b600080fd5b61018d6101a2366004614623565b6103ce565b3480156101b357600080fd5b5061018d6101c23660046147c5565b6104d1565b3480156101d357600080fd5b5061018d6101e2366004614900565b610a50565b3480156101f357600080fd5b5061018d610202366004614a18565b610f85565b34801561021357600080fd5b5061018d610222366004614a9e565b61104c565b61018d610235366004614bb6565b611098565b61018d610248366004614bb6565b6115ce565b34801561025957600080fd5b506102817f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d60781565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102aa57600080fd5b506102be6102b9366004614cb6565b611b17565b604051610295929190614d52565b3480156102d857600080fd5b506102817f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127081565b61018d61030e366004614d6d565b61206b565b61018d610321366004614e62565b6120b3565b34801561033257600080fd5b506102817f000000000000000000000000cf083be4164828f00cae704ec15a36d71149128481565b34801561036657600080fd5b5061018d6103753660046147c5565b6125cc565b34801561038657600080fd5b5061018d610395366004614f57565b612b00565b3480156103a657600080fd5b506102817f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d60781565b6002600054036103f05760405162461bcd60e51b815260040161018490614fc2565b6002600090815560408051630d0e30db60e41b8152905134927f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270926001600160a01b0384169263d0e30db09286926004808201939182900301818588803b15801561045a57600080fd5b505af115801561046e573d6000803e3d6000fd5b505050505061048281838989898989612fc2565b604080518381526001600160a01b03851660208201527f0864d9de329ff01fb0e285c707907ad33167daca48ee5c1c7c4edc5ebd553e78910160405180910390a1505060016000555050505050565b6002600054036104f35760405162461bcd60e51b815260040161018490614fc2565b600260009081556040516378ed5d1f60e01b8152600481018390526001600160a01b038416906378ed5d1f906024016020604051808303816000875af1158015610541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105659190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c99190614ff9565b6001600160a01b03168b6000815181106105e5576105e5615016565b60200260200101516001600160a01b031614801561068f5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106609190614ff9565b6001600160a01b03168b60018151811061067c5761067c615016565b60200260200101516001600160a01b0316145b806107bd5750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f79190614ff9565b6001600160a01b03168b60018151811061071357610713615016565b60200260200101516001600160a01b03161480156107bd5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561076a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078e9190614ff9565b6001600160a01b03168b6000815181106107aa576107aa615016565b60200260200101516001600160a01b0316145b6108175760405162461bcd60e51b815260206004820152602560248201527f417065537761705a61703a2057726f6e67204c50207061697220666f72204d696044820152646e6941706560d81b6064820152608401610184565b61082a8d8d8d8d8d8d8d8d8d308e613404565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610871573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610895919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906108c69087908590600401615045565b6020604051808303816000875af11580156108e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610909919061505e565b50604051638dbdbe6d60e01b815260048101849052602481018290523360448201526001600160a01b03851690638dbdbe6d90606401600060405180830381600087803b15801561095957600080fd5b505af115801561096d573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b391506109a0908790600090600401615045565b6020604051808303816000875af11580156109bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e3919061505e565b507ff1ee85beaab4e417aa82356a1987f34c8a4d209194bc93a445b4dbf570c880938e8e85604051610a33939291906001600160a01b039390931683526020830191909152604082015260600190565b60405180910390a150506001600055505050505050505050505050565b600260005403610a725760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000816001600160a01b0316631c39b6726040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade9190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b429190614ff9565b6001600160a01b03168a600081518110610b5e57610b5e615016565b60200260200101516001600160a01b0316148015610c085750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd99190614ff9565b6001600160a01b03168a600181518110610bf557610bf5615016565b60200260200101516001600160a01b0316145b80610d365750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c709190614ff9565b6001600160a01b03168a600181518110610c8c57610c8c615016565b60200260200101516001600160a01b0316148015610d365750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d079190614ff9565b6001600160a01b03168a600081518110610d2357610d23615016565b60200260200101516001600160a01b0316145b610d525760405162461bcd60e51b815260040161018490615080565b610d658c8c8c8c8c8c8c8c8c308d613404565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610dac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd0919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b390610e019086908590600401615045565b6020604051808303816000875af1158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e44919061505e565b506040516370aff70f60e01b8152600481018290523360248201526001600160a01b038416906370aff70f90604401600060405180830381600087803b158015610e8d57600080fd5b505af1158015610ea1573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b39150610ed4908690600090600401615045565b6020604051808303816000875af1158015610ef3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f17919061505e565b507f7d3698d30ac93ff91cb00b4e12cadd07e613ef452b72a2f503e27d066a58856e8d8d85604051610f69939291906001600160a01b0393841681526020810192909252909116604082015260600190565b60405180910390a1505060016000555050505050505050505050565b600260005403610fa75760405162461bcd60e51b815260040161018490614fc2565b60026000908155610fb78861349a565b9050610fce6001600160a01b03891633308a61350b565b80610fd88961349a565b610fe291906150c2565b9650610ff388888888888888612fc2565b604080516001600160a01b038a81168252602082018a905284168183015290517f7b69944e54cb50e622cc9c3d1091a7ab275297c06c997ea6ef7a56ce58d878159181900360600190a150506001600055505050505050565b60026000540361106e5760405162461bcd60e51b815260040161018490614fc2565b60026000556110868b8b8b8b8b8b8b8b8b8b8b613404565b50506001600055505050505050505050565b6002600054036110ba5760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000826001600160a01b031663dbc162de6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111289190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611168573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118c9190614ff9565b6001600160a01b03168b6000815181106111a8576111a8615016565b60200260200101516001600160a01b03161480156112525750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112239190614ff9565b6001600160a01b03168b60018151811061123f5761123f615016565b60200260200101516001600160a01b0316145b806113805750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190614ff9565b6001600160a01b03168b6001815181106112d6576112d6615016565b60200260200101516001600160a01b03161480156113805750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561132d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113519190614ff9565b6001600160a01b03168b60008151811061136d5761136d615016565b60200260200101516001600160a01b0316145b61139c5760405162461bcd60e51b8152600401610184906150e7565b6113ad8b8b8b8b8b8b8b308c61357c565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156113f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611418919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906114499087908590600401615045565b6020604051808303816000875af1158015611468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148c919061505e565b50604051638dbdbe6d60e01b815260048101829052602481018490523360448201526001600160a01b03851690638dbdbe6d906064016020604051808303816000875af11580156114e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611505919061502c565b5060405163095ea7b360e01b81526001600160a01b0383169063095ea7b390611535908790600090600401615045565b6020604051808303816000875af1158015611554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611578919061505e565b50604080513481526001600160a01b03861660208201527fbba058d4778dd4dfe5b28e159c111e8a68aefcb03e525413f08586f1ab6770d191015b60405180910390a15050600160005550505050505050505050565b6002600054036115f05760405162461bcd60e51b815260040161018490614fc2565b600260009081556040516378ed5d1f60e01b8152600481018390526001600160a01b038416906378ed5d1f906024016020604051808303816000875af115801561163e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116629190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c69190614ff9565b6001600160a01b03168b6000815181106116e2576116e2615016565b60200260200101516001600160a01b031614801561178c5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611739573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175d9190614ff9565b6001600160a01b03168b60018151811061177957611779615016565b60200260200101516001600160a01b0316145b806118ba5750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f49190614ff9565b6001600160a01b03168b60018151811061181057611810615016565b60200260200101516001600160a01b03161480156118ba5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b9190614ff9565b6001600160a01b03168b6000815181106118a7576118a7615016565b60200260200101516001600160a01b0316145b6119165760405162461bcd60e51b815260206004820152602760248201527f417065537761705a61703a2057726f6e67204c50207061697220666f72204475604482015266616c204661726d60c81b6064820152608401610184565b6119278b8b8b8b8b8b8b308c61357c565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561196e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611992919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906119c39087908590600401615045565b6020604051808303816000875af11580156119e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a06919061505e565b50604051638dbdbe6d60e01b815260048101849052602481018290523360448201526001600160a01b03851690638dbdbe6d90606401600060405180830381600087803b158015611a5657600080fd5b505af1158015611a6a573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b39150611a9d908790600090600401615045565b6020604051808303816000875af1158015611abc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae0919061505e565b5060408051348152602081018590527fe7eb221216ecf3b8c976ba85c999fddecc26f0f4ecb57451371f6ad6111994fe91016115b3565b611b1f614592565b611b27614592565b600285101580611b38575060028310155b611b905760405162461bcd60e51b815260206004820152602360248201527f417065537761705a61703a204e65656473206174206c65617374206f6e6520706044820152620c2e8d60eb1b6064820152608401610184565b6000611b9d60028961512a565b9050808615611c6b5760405163d06ca61f60e01b81526000906001600160a01b037f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607169063d06ca61f90611bf99086908d908d90600401615195565b600060405180830381865afa158015611c16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c3e91908101906151b8565b90508060018251611c4f91906150c2565b81518110611c5f57611c5f615016565b60200260200101519150505b818515611d375760405163d06ca61f60e01b81526000906001600160a01b037f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607169063d06ca61f90611cc59087908c908c90600401615195565b600060405180830381865afa158015611ce2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d0a91908101906151b8565b90508060018251611d1b91906150c2565b81518110611d2b57611d2b615016565b60200260200101519150505b60008815611d75578989611d4c6001826150c2565b818110611d5b57611d5b615016565b9050602002016020810190611d70919061523d565b611d9d565b87876000818110611d8857611d88615016565b9050602002016020810190611d9d919061523d565b905060008715611ddd578888611db46001826150c2565b818110611dc357611dc3615016565b9050602002016020810190611dd8919061523d565b611e05565b8a8a6000818110611df057611df0615016565b9050602002016020810190611e05919061523d565b60405163e6a4390560e01b81526001600160a01b03848116600483015280831660248301529192506000917f000000000000000000000000cf083be4164828f00cae704ec15a36d711491284169063e6a4390590604401602060405180830381865afa158015611e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9d9190614ff9565b9050600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611ee0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f049190615271565b506001600160701b031691506001600160701b03169150826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7d9190614ff9565b6001600160a01b0316856001600160a01b031603611f9757905b604051632b58577b60e21b81526004810188905260248101839052604481018290526000907f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d6076001600160a01b03169063ad615dec90606401602060405180830381865afa15801561200d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612031919061502c565b6040805180820182528a815260208082019a909a5281518083019092529981529788015250959e949d50939b505050505050505050505050565b60026000540361208d5760405162461bcd60e51b815260040161018490614fc2565b60026000556120a389898989898989898961357c565b5050600160005550505050505050565b6002600054036120d55760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000816001600160a01b0316631c39b6726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561211d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121419190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612181573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a59190614ff9565b6001600160a01b03168a6000815181106121c1576121c1615016565b60200260200101516001600160a01b031614801561226b5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223c9190614ff9565b6001600160a01b03168a60018151811061225857612258615016565b60200260200101516001600160a01b0316145b806123995750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d39190614ff9565b6001600160a01b03168a6001815181106122ef576122ef615016565b60200260200101516001600160a01b03161480156123995750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236a9190614ff9565b6001600160a01b03168a60008151811061238657612386615016565b60200260200101516001600160a01b0316145b6123b55760405162461bcd60e51b815260040161018490615080565b6123c68a8a8a8a8a8a8a308b61357c565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561240d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612431919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b3906124629086908590600401615045565b6020604051808303816000875af1158015612481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a5919061505e565b506040516370aff70f60e01b8152600481018290523360248201526001600160a01b038416906370aff70f90604401600060405180830381600087803b1580156124ee57600080fd5b505af1158015612502573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b39150612535908690600090600401615045565b6020604051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061505e565b50604080513481526001600160a01b03851660208201527f0508054cbbbec64f9a98657481af938dae1891415b0863ccc3402ac1382577a5910160405180910390a150506001600055505050505050505050565b6002600054036125ee5760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000826001600160a01b031663dbc162de6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612638573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265c9190614ff9565b9050806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c09190614ff9565b6001600160a01b03168b6000815181106126dc576126dc615016565b60200260200101516001600160a01b03161480156127865750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612733573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127579190614ff9565b6001600160a01b03168b60018151811061277357612773615016565b60200260200101516001600160a01b0316145b806128b45750806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ee9190614ff9565b6001600160a01b03168b60018151811061280a5761280a615016565b60200260200101516001600160a01b03161480156128b45750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128859190614ff9565b6001600160a01b03168b6000815181106128a1576128a1615016565b60200260200101516001600160a01b0316145b6128d05760405162461bcd60e51b8152600401610184906150e7565b6128e38d8d8d8d8d8d8d8d8d308e613404565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561292a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294e919061502c565b60405163095ea7b360e01b81529091506001600160a01b0383169063095ea7b39061297f9087908590600401615045565b6020604051808303816000875af115801561299e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c2919061505e565b50604051638dbdbe6d60e01b815260048101829052602481018490523360448201526001600160a01b03851690638dbdbe6d906064016020604051808303816000875af1158015612a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3b919061502c565b5060405163095ea7b360e01b81526001600160a01b0383169063095ea7b390612a6b908790600090600401615045565b6020604051808303816000875af1158015612a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aae919061505e565b507f452471abcb188a45e0b1afd12999cf4df9ed51c4b01cf813bbbdabaa9b382cad8e8e86604051610a33939291906001600160a01b0393841681526020810192909252909116604082015260600190565b600260005403612b225760405162461bcd60e51b815260040161018490614fc2565b60026000819055506000876001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8e9190614ff9565b90506000886001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf49190614ff9565b9050612c0b6001600160a01b038a1633308b61350b565b60405163095ea7b360e01b81526001600160a01b038a169063095ea7b390612c39908d908c90600401615045565b6020604051808303816000875af1158015612c58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7c919061505e565b50604051635d5155ef60e11b81526001600160a01b0383811660048301528281166024830152604482018a905260648201899052608482018890523060a483015260c4820185905260009182918d169063baa2abde9060e40160408051808303816000875af1158015612cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1791906152c1565b60405163095ea7b360e01b815291935091506001600160a01b0385169063095ea7b390612d6a907f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607908690600401615045565b6020604051808303816000875af1158015612d89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dad919061505e565b5060405163095ea7b360e01b81526001600160a01b0384169063095ea7b390612dfc907f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607908590600401615045565b6020604051808303816000875af1158015612e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e3f919061505e565b506000807f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d6076001600160a01b031663e8e33700878787878e8e338f6040518963ffffffff1660e01b8152600401612e9d9897969594939291906152e5565b6060604051808303816000875af1158015612ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee0919061532e565b5090925090506000612ef283866150c2565b1115612f1757612f1733612f0684876150c2565b6001600160a01b0389169190613675565b6000612f2382856150c2565b1115612f4857612f4833612f3783866150c2565b6001600160a01b0388169190613675565b7fbef8fc428932b971d2badb42f83b58752429ad4733367b71f4bddbd2023b99f88d8f7f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d6078f604051610a3394939291906001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6000816001600160a01b0316631c39b6726040518163ffffffff1660e01b8152600401602060405180830381865afa158015613002573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130269190614ff9565b9050866001600160a01b03898116908316146132b457886001600160a01b03168787600081811061305957613059615016565b905060200201602081019061306e919061523d565b6001600160a01b0316146130c45760405162461bcd60e51b815260206004820152601e60248201527f417065537761705a61703a2077726f6e67207061746820706174685b305d00006044820152606401610184565b6001600160a01b03821687876130db6001826150c2565b8181106130ea576130ea615016565b90506020020160208101906130ff919061523d565b6001600160a01b0316146131555760405162461bcd60e51b815260206004820152601f60248201527f417065537761705a61703a2077726f6e67207061746820706174685b2d315d006044820152606401610184565b60405163095ea7b360e01b81526001600160a01b038a169063095ea7b3906131a3907f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607908c90600401615045565b6020604051808303816000875af11580156131c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e6919061505e565b506040516338ed173960e01b81526000906001600160a01b037f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d60716906338ed173990613240908c908a908d908d9030908d9060040161535c565b6000604051808303816000875af115801561325f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261328791908101906151b8565b9050806001825161329891906150c2565b815181106132a8576132a8615016565b60200260200101519150505b60405163095ea7b360e01b81526001600160a01b0383169063095ea7b3906132e29086908590600401615045565b6020604051808303816000875af1158015613301573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613325919061505e565b506040516370aff70f60e01b8152600481018290523360248201526001600160a01b038416906370aff70f90604401600060405180830381600087803b15801561336e57600080fd5b505af1158015613382573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b038516925063095ea7b391506133b5908690600090600401615045565b6020604051808303816000875af11580156133d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f8919061505e565b50505050505050505050565b600061340f8c61349a565b90506134266001600160a01b038d1633308e61350b565b806134308d61349a565b61343a91906150c2565b9a506134518c8c8c8c8c8c8c8c8c8c8c6000613699565b7f1fd2bf03b44ce5cb29193cc54927f3fae3203d6bee3b52fa2b41b0ae38d9dd7d8c8c8c604051613484939291906153d3565b60405180910390a1505050505050505050505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156134e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613505919061502c565b92915050565b6040516001600160a01b03808516602483015283166044820152606481018290526135769085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526141ca565b50505050565b600034905060007f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127090507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561360157600080fd5b505af1158015613615573d6000803e3d6000fd5b505050505061362f81838d8d8d8d8d8d8d8d8d6001613699565b7f2e4eeaaef6f24db22c68d3447461155fb43767e27eefa5655f863218ab23aa04828c6040516136609291906153fa565b60405180910390a15050505050505050505050565b6136948363a9059cbb60e01b848460405160240161353f929190615045565b505050565b6001600160a01b0383166136fd5760405162461bcd60e51b815260206004820152602560248201527f417065537761705a61703a2043616e2774207a617020746f206e756c6c206164604482015264647265737360d81b6064820152608401610184565b89516002146137655760405162461bcd60e51b815260206004820152602e60248201527f417065537761705a61703a206e6565642065786163746c79203220746f6b656e60448201526d07320746f20666f726d2061204c560941b6064820152608401610184565b60006001600160a01b03167f000000000000000000000000cf083be4164828f00cae704ec15a36d7114912846001600160a01b031663e6a439058c6000815181106137b2576137b2615016565b60200260200101518d6001815181106137cd576137cd615016565b60200260200101516040518363ffffffff1660e01b81526004016138079291906001600160a01b0392831681529116602082015260400190565b602060405180830381865afa158015613824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138489190614ff9565b6001600160a01b03160361389e5760405162461bcd60e51b815260206004820152601e60248201527f417065537761705a61703a205061697220646f65736e277420657869737400006044820152606401610184565b6138c260405180606001604052806000815260200160008152602001600081525090565b8c6001600160a01b031663095ea7b37f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d6078e6040518363ffffffff1660e01b8152600401613910929190615045565b6020604051808303816000875af115801561392f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613953919061505e565b5061395f60028d61512a565b81526000604082018190528b516001600160a01b038f16918d9161398557613985615016565b60200260200101516001600160a01b031614613bdc578c6001600160a01b03168a8a60008181106139b8576139b8615016565b90506020020160208101906139cd919061523d565b6001600160a01b031614613a235760405162461bcd60e51b815260206004820152601f60248201527f417065537761705a61703a2077726f6e6720706174682070617468305b305d006044820152606401610184565b8a600081518110613a3657613a36615016565b60209081029190910101516001600160a01b03168a8a613a576001826150c2565b818110613a6657613a66615016565b9050602002016020810190613a7b919061523d565b6001600160a01b031614613ad15760405162461bcd60e51b815260206004820181905260248201527f417065537761705a61703a2077726f6e6720706174682070617468305b2d315d6044820152606401610184565b613af48b600081518110613ae757613ae7615016565b602002602001015161349a565b6040820152805186516001600160a01b037f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d60716916338ed1739918990600090613b3f57613b3f615016565b60200260200101518d8d30896040518763ffffffff1660e01b8152600401613b6c9695949392919061535c565b6000604051808303816000875af1158015613b8b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613bb391908101906151b8565b508060400151613bcf8c600081518110613ae757613ae7615016565b613bd991906150c2565b81525b613be760028d61512a565b60208201528a516001600160a01b038e16908c906001908110613c0c57613c0c615016565b60200260200101516001600160a01b031614613e5e578c6001600160a01b031688886000818110613c3f57613c3f615016565b9050602002016020810190613c54919061523d565b6001600160a01b031614613caa5760405162461bcd60e51b815260206004820152601f60248201527f417065537761705a61703a2077726f6e6720706174682070617468315b305d006044820152606401610184565b8a600181518110613cbd57613cbd615016565b60209081029190910101516001600160a01b03168888613cde6001826150c2565b818110613ced57613ced615016565b9050602002016020810190613d02919061523d565b6001600160a01b031614613d585760405162461bcd60e51b815260206004820181905260248201527f417065537761705a61703a2077726f6e6720706174682070617468315b2d315d6044820152606401610184565b613d6e8b600181518110613ae757613ae7615016565b8160400181815250507f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d6076001600160a01b03166338ed1739826020015188600181518110613dbe57613dbe615016565b60200260200101518b8b30896040518763ffffffff1660e01b8152600401613deb9695949392919061535c565b6000604051808303816000875af1158015613e0a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e3291908101906151b8565b508060400151613e4e8c600181518110613ae757613ae7615016565b613e5891906150c2565b60208201525b8a600081518110613e7157613e71615016565b60200260200101516001600160a01b031663095ea7b37f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d60783600001516040518363ffffffff1660e01b8152600401613eca929190615045565b6020604051808303816000875af1158015613ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f0d919061505e565b508a600181518110613f2157613f21615016565b60200260200101516001600160a01b031663095ea7b37f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d60783602001516040518363ffffffff1660e01b8152600401613f7a929190615045565b6020604051808303816000875af1158015613f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbd919061505e565b506000807f000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d6076001600160a01b031663e8e337008e60008151811061400357614003615016565b60200260200101518f60018151811061401e5761401e615016565b6020026020010151866000015187602001518c60008151811061404357614043615016565b60200260200101518d60018151811061405e5761405e615016565b60200260200101518d8d6040518963ffffffff1660e01b815260040161408b9897969594939291906152e5565b6060604051808303816000875af11580156140aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140ce919061532e565b50915091507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b03168d60008151811061411057614110615016565b60200260200101516001600160a01b03160361418d5761415a8d60018151811061413c5761413c615016565b602002602001015182856020015161415491906150c2565b8661429c565b6141888d60008151811061417057614170615016565b602002602001015183856000015161415491906150c2565b6141b9565b6141a38d60008151811061417057614170615016565b6141b98d60018151811061413c5761413c615016565b505050505050505050505050505050565b600061421f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661440f9092919063ffffffff16565b805190915015613694578080602001905181019061423d919061505e565b6136945760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610184565b816000036142a957505050565b7f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316836001600160a01b03161480156142e75750805b156143fb57604051632e1a7d4d60e01b8152600481018390527f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561434e57600080fd5b505af1158015614362573d6000803e3d6000fd5b50506040516000925033915061132390859084818181858888f193505050503d80600081146143ad576040519150601f19603f3d011682016040523d82523d6000602084013e6143b2565b606091505b50509050806135765760405162461bcd60e51b81526020600482015260156024820152743730ba34bb32903a3930b739b332b91032b93937b960591b6044820152606401610184565b6136946001600160a01b0384163384613675565b606061441e8484600085614428565b90505b9392505050565b6060824710156144895760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610184565b6001600160a01b0385163b6144e05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610184565b600080866001600160a01b031685876040516144fc919061543f565b60006040518083038185875af1925050503d8060008114614539576040519150601f19603f3d011682016040523d82523d6000602084013e61453e565b606091505b509150915061454e828286614559565b979650505050505050565b60608315614568575081614421565b8251156145785782518084602001fd5b8160405162461bcd60e51b8152600401610184919061545b565b60405180604001604052806002906020820280368337509192915050565b60008083601f8401126145c257600080fd5b5081356001600160401b038111156145d957600080fd5b6020830191508360208260051b85010111156145f457600080fd5b9250929050565b6001600160a01b038116811461461057600080fd5b50565b803561461e816145fb565b919050565b60008060008060006080868803121561463b57600080fd5b85356001600160401b0381111561465157600080fd5b61465d888289016145b0565b9096509450506020860135925060408601359150606086013561467f816145fb565b809150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156146cb576146cb61468d565b604052919050565b60006001600160401b038211156146ec576146ec61468d565b5060051b60200190565b600082601f83011261470757600080fd5b8135602061471c614717836146d3565b6146a3565b82815260059290921b8401810191818101908684111561473b57600080fd5b8286015b8481101561475f578035614752816145fb565b835291830191830161473f565b509695505050505050565b600082601f83011261477b57600080fd5b8135602061478b614717836146d3565b82815260059290921b840181019181810190868411156147aa57600080fd5b8286015b8481101561475f57803583529183019183016147ae565b6000806000806000806000806000806000806101408d8f0312156147e857600080fd5b6147f18d614613565b9b5060208d01359a506001600160401b0360408e0135111561481257600080fd5b6148228e60408f01358f016146f6565b99506001600160401b0360608e0135111561483c57600080fd5b61484c8e60608f01358f016145b0565b90995097506001600160401b0360808e0135111561486957600080fd5b6148798e60808f01358f016145b0565b90975095506001600160401b0360a08e0135111561489657600080fd5b6148a68e60a08f01358f0161476a565b94506001600160401b0360c08e013511156148c057600080fd5b6148d08e60c08f01358f0161476a565b935060e08d013592506148e66101008e01614613565b91506101208d013590509295989b509295989b509295989b565b60008060008060008060008060008060006101208c8e03121561492257600080fd5b61492b8c614613565b9a5060208c013599506001600160401b038060408e0135111561494d57600080fd5b61495d8e60408f01358f016146f6565b99508060608e0135111561497057600080fd5b6149808e60608f01358f016145b0565b909950975060808d013581101561499657600080fd5b6149a68e60808f01358f016145b0565b909750955060a08d01358110156149bc57600080fd5b6149cc8e60a08f01358f0161476a565b94508060c08e013511156149df57600080fd5b506149f08d60c08e01358e0161476a565b925060e08c01359150614a066101008d01614613565b90509295989b509295989b9093969950565b600080600080600080600060c0888a031215614a3357600080fd5b8735614a3e816145fb565b96506020880135955060408801356001600160401b03811115614a6057600080fd5b614a6c8a828b016145b0565b909650945050606088013592506080880135915060a0880135614a8e816145fb565b8091505092959891949750929550565b60008060008060008060008060008060006101208c8e031215614ac057600080fd5b614ac98c614613565b9a5060208c013599506001600160401b038060408e01351115614aeb57600080fd5b614afb8e60408f01358f016146f6565b99508060608e01351115614b0e57600080fd5b614b1e8e60608f01358f016145b0565b909950975060808d0135811015614b3457600080fd5b614b448e60808f01358f016145b0565b909750955060a08d0135811015614b5a57600080fd5b614b6a8e60a08f01358f0161476a565b94508060c08e01351115614b7d57600080fd5b50614b8e8d60c08e01358e0161476a565b9250614b9c60e08d01614613565b91506101008c013590509295989b509295989b9093969950565b6000806000806000806000806000806101008b8d031215614bd657600080fd5b8a356001600160401b0380821115614bed57600080fd5b614bf98e838f016146f6565b9b5060208d0135915080821115614c0f57600080fd5b614c1b8e838f016145b0565b909b50995060408d0135915080821115614c3457600080fd5b614c408e838f016145b0565b909950975060608d0135915080821115614c5957600080fd5b614c658e838f0161476a565b965060808d0135915080821115614c7b57600080fd5b50614c888d828e0161476a565b94505060a08b01359250614c9e60c08c01614613565b915060e08b013590509295989b9194979a5092959850565b600080600080600060608688031215614cce57600080fd5b8535945060208601356001600160401b0380821115614cec57600080fd5b614cf889838a016145b0565b90965094506040880135915080821115614d1157600080fd5b50614d1e888289016145b0565b969995985093965092949392505050565b8060005b6002811015613576578151845260209384019390910190600101614d33565b60808101614d608285614d2f565b6144216040830184614d2f565b600080600080600080600080600060e08a8c031215614d8b57600080fd5b89356001600160401b0380821115614da257600080fd5b614dae8d838e016146f6565b9a5060208c0135915080821115614dc457600080fd5b614dd08d838e016145b0565b909a50985060408c0135915080821115614de957600080fd5b614df58d838e016145b0565b909850965060608c0135915080821115614e0e57600080fd5b614e1a8d838e0161476a565b955060808c0135915080821115614e3057600080fd5b50614e3d8c828d0161476a565b935050614e4c60a08b01614613565b915060c08a013590509295985092959850929598565b600080600080600080600080600060e08a8c031215614e8057600080fd5b89356001600160401b0380821115614e9757600080fd5b614ea38d838e016146f6565b9a5060208c0135915080821115614eb957600080fd5b614ec58d838e016145b0565b909a50985060408c0135915080821115614ede57600080fd5b614eea8d838e016145b0565b909850965060608c0135915080821115614f0357600080fd5b614f0f8d838e0161476a565b955060808c0135915080821115614f2557600080fd5b50614f328c828d0161476a565b93505060a08a01359150614f4860c08b01614613565b90509295985092959850929598565b600080600080600080600080610100898b031215614f7457600080fd5b8835614f7f816145fb565b97506020890135614f8f816145fb565b979a9799505050506040860135956060810135956080820135955060a0820135945060c0820135935060e0909101359150565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561500b57600080fd5b8151614421816145fb565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561503e57600080fd5b5051919050565b6001600160a01b03929092168252602082015260400190565b60006020828403121561507057600080fd5b8151801515811461442157600080fd5b60208082526022908201527f417065537761705a61703a2057726f6e67204c50207061697220666f7220506f6040820152611bdb60f21b606082015260800190565b6000828210156150e257634e487b7160e01b600052601160045260246000fd5b500390565b60208082526023908201527f417065537761705a61703a2057726f6e67204c50207061697220666f722054426040820152621a5b1b60ea1b606082015260800190565b60008261514757634e487b7160e01b600052601260045260246000fd5b500490565b8183526000602080850194508260005b8581101561518a57813561516f816145fb565b6001600160a01b03168752958201959082019060010161515c565b509495945050505050565b8381526040602082015260006151af60408301848661514c565b95945050505050565b600060208083850312156151cb57600080fd5b82516001600160401b038111156151e157600080fd5b8301601f810185136151f257600080fd5b8051615200614717826146d3565b81815260059190911b8201830190838101908783111561521f57600080fd5b928401925b8284101561454e57835182529284019290840190615224565b60006020828403121561524f57600080fd5b8135614421816145fb565b80516001600160701b038116811461461e57600080fd5b60008060006060848603121561528657600080fd5b61528f8461525a565b925061529d6020850161525a565b9150604084015163ffffffff811681146152b657600080fd5b809150509250925092565b600080604083850312156152d457600080fd5b505080516020909101519092909150565b6001600160a01b039889168152968816602088015260408701959095526060860193909352608085019190915260a084015290921660c082015260e08101919091526101000190565b60008060006060848603121561534357600080fd5b8351925060208401519150604084015190509250925092565b86815285602082015260a06040820152600061537c60a08301868861514c565b6001600160a01b039490941660608301525060800152949350505050565b600081518084526020808501945080840160005b8381101561518a5781516001600160a01b0316875295820195908201906001016153ae565b60018060a01b03841681528260208201526060604082015260006151af606083018461539a565b82815260406020820152600061441e604083018461539a565b60005b8381101561542e578181015183820152602001615416565b838111156135765750506000910152565b60008251615451818460208701615413565b9190910192915050565b602081526000825180602084015261547a816040850160208701615413565b601f01601f1916919091016040019291505056fea2646970667358221220b46a0a8722f6adc5357af1f5e8adb776f4bc252f2183d4828cfa5511591c647064736f6c634300080f0033

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

000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607

-----Decoded View---------------
Arg [0] : _router (address): 0xC0788A3aD43d79aa53B09c2EaCc313A787d1d607

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000c0788a3ad43d79aa53b09c2eacc313a787d1d607


Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

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

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