Contract 0x0c53551118ca4c01db0dea234c73a728b16e4f70

Contract Overview

Balance:
0 FTM

FTM Value:
$0.00

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x0bcd4002fc0e1a2306402be4b3944e668323954be292b087f0c3639702840e8dHarvest242539952021-12-07 12:42:065 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.128167568177
0x2f6286fac10f83ed479dcb1c9f6fea6b23cc3fafded562eedfd76454fbccb457Harvest242535992021-12-07 12:36:4011 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.100398289225
0x8c2a0950d15941a8f685bb0bf5cff4da573433cb29bb37ff9ca27fd2d646df33Harvest242532572021-12-07 12:31:2016 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.098506088102
0x2c5b5fcbe40412b40a3725ca8bab9a462a1819ab79e7f435e4ef7e92e71ff900Harvest242529542021-12-07 12:26:4820 mins ago0xff9f147c7724b858a99b2a9c19b6065ea9c06c53 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.093100984663
0x31426083625ac7cff632cdef07e45dae6dc3ba6e2474007b81a745f842dd5c84Harvest242526492021-12-07 12:22:2425 mins ago0xff9f147c7724b858a99b2a9c19b6065ea9c06c53 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.088552752907
0x0cf4444a8b1e1bfe0f19fa0634c30060b236d5276d7c01db5638bec80282d43fHarvest242523712021-12-07 12:18:4528 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.096631295402
0xe7fb02df4266f72984392fbf68d5be2fc2a587fdb42ac9806dbadb742c8a1126Harvest242520692021-12-07 12:14:5132 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.095125504043
0x254ca16f92db64dcf7534ef1cf688068db985f8daccb302575dd4e3b622e482cHarvest242517722021-12-07 12:10:5536 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.111747754505
0xc5fa790cf5be129ccea9d6c84a8f82464f36b9064cc5684466c68e2278356381Harvest242514272021-12-07 12:05:5041 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.102955713212
0x1903166ba50bf0bae7c18dd6b8a2bc8f0829134f09ada675acf2e57edac5ebfeHarvest242511082021-12-07 12:01:1846 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.097294607624
0x4676b4f4211cfef2b3d5873d7e838a50519dbf1318666d57ab09ad26ddef81d2Harvest242508062021-12-07 11:57:0250 mins ago0xff9f147c7724b858a99b2a9c19b6065ea9c06c53 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.103612566139
0xf1e2b1d4ac0e5c9bbeaf19773ad02423821a96c9eed80f1b0500aa916894d48eHarvest242504652021-12-07 11:52:2955 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.107252332256
0x13e5e1eb52de2a2be7643e8e1a266f488f5f8fa92452909c229a30bcc7b94119Harvest242501322021-12-07 11:47:4659 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.111634466151
0xdf191a9b05d6ee2607adc997e1d7640824b23cd992d3d3b95d3684841893d4c1Harvest242497072021-12-07 11:41:221 hr 6 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.128923143918
0xb0a6b39de6e2391b702336b8917c0e8fd40dddb862c312d0dcd4ab83e8ddf522Harvest242492872021-12-07 11:34:191 hr 13 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.071363547253
0x3da518917a793111eca6d71dc75f446573cc118fdf7fa432e42bb27c0874c552Harvest242490632021-12-07 11:31:101 hr 16 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.085465664611
0xbfe99facaf75bb394252e905848e65c968241e17f77199e97cd3c9767953d0adHarvest242487972021-12-07 11:27:301 hr 20 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.092731307909
0x0f3aa09218fe3aa81b4201b91052fe3ff6b07a138d700873921fda9c9e8878f4Harvest242485042021-12-07 11:23:351 hr 24 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.092762567073
0x8ea7bcd96e7b7ce106dacbd142e4fb0aff6ba6b81ac17e507ed411bf5187486cHarvest242482162021-12-07 11:19:491 hr 27 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.089073740475
0x8839a004e3f7a53c07d1fced66c0f6b59f917d2c39228b71f56c251229ef9435Harvest242479372021-12-07 11:16:101 hr 31 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.090431897756
0x1f81a89452e85da92c7179b451c873818c473ca32ca9d5f9288495663a7c4dc9Harvest242475622021-12-07 11:11:021 hr 36 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.09952481498
0x01c7c25ea0bf015a1a5e22979d971d29861436c1b453bc4db15a9900aa3377b5Harvest242469382021-12-07 11:03:061 hr 44 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.112274228687
0x6fb30f9a8a1b14cb6baaf8ef9f13c081c3365bf63a3a7aaf418bcfd182b47d4aHarvest242462462021-12-07 10:53:121 hr 54 mins ago0xff96fd2c04b9f52cdca9ee2d99653ea268a3704b IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.108095086464
0x9236e932b731caa9f793f3060129ef1f1e54116ff17db3eb73d86acd4477ce2bHarvest242455782021-12-07 10:43:332 hrs 4 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.112729926821
0x8c693e1e69d67650f38308831464382d43b3ddb435d76dc7f1afcb0171e21710Harvest242448892021-12-07 10:32:552 hrs 14 mins ago0xffd3ed4c00128143466c5ae011f33ee3b1059c86 IN  0x0c53551118ca4c01db0dea234c73a728b16e4f700 FTM0.115930032264
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0xed32b42c6c42916f78f2707919bdc6784ec8b1e8eb504865b009d881447650ed231526862021-11-26 4:19:4011 days 8 hrs ago 0xe1610bb38ce95254dd77cbc82f9c1148569b560e  Contract Creation0 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ReaperAutoCompoundBeethoven_fBEETS

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at FtmScan.com on 2021-11-26
*/

/**
 *Submitted for verification at FtmScan.com on 2021-09-10
*/
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
// File: @openzeppelin/contracts/access/Ownable.sol


pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @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);
}

// File: @openzeppelin/contracts/math/SafeMath.sol




pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 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);
            }
        }
    }
}


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

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

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



// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}







// File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol


pragma solidity ^0.8.0;


/**
 * @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: @openzeppelin/contracts/utils/Pausable.sol


pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}



interface IAuthorizer {
    /**
     * @dev Returns true if `account` can perform the action described by `actionId` in the contract `where`.
     */
    function canPerform(
        bytes32 actionId,
        address account,
        address where
    ) external view returns (bool);
}

interface IPoolToken {
    function getPoolTokens(bytes32 poolId)
        external
        returns (
            IERC20[] memory,
            uint256[] memory,
            uint256
        );
}



interface IPoolSwapStructs {
    // This is not really an interface - it just defines common structs used by other interfaces: IGeneralPool and
    // IMinimalSwapInfoPool.
    //
    // This data structure represents a request for a token swap, where `kind` indicates the swap type ('given in' or
    // 'given out') which indicates whether or not the amount sent by the pool is known.
    //
    // The pool receives `tokenIn` and sends `tokenOut`. `amount` is the number of `tokenIn` tokens the pool will take
    // in, or the number of `tokenOut` tokens the Pool will send out, depending on the given swap `kind`.
    //
    // All other fields are not strictly necessary for most swaps, but are provided to support advanced scenarios in
    // some Pools.
    //
    // `poolId` is the ID of the Pool involved in the swap - this is useful for Pool contracts that implement more than
    // one Pool.
    //
    // The meaning of `lastChangeBlock` depends on the Pool specialization:
    //  - Two Token or Minimal Swap Info: the last block in which either `tokenIn` or `tokenOut` changed its total
    //    balance.
    //  - General: the last block in which *any* of the Pool's registered tokens changed its total balance.
    //
    // `from` is the origin address for the funds the Pool receives, and `to` is the destination address
    // where the Pool sends the outgoing tokens.
    //
    // `userData` is extra data provided by the caller - typically a signature from a trusted party.
    struct SwapRequest {
        IVault.SwapKind kind;
        IERC20 tokenIn;
        IERC20 tokenOut;
        uint256 amount;
        // Misc data
        bytes32 poolId;
        uint256 lastChangeBlock;
        address from;
        address to;
        bytes userData;
    }
}

interface IBasePool is IPoolSwapStructs {
    /**
     * @dev Called by the Vault when a user calls `IVault.joinPool` to add liquidity to this Pool. Returns how many of
     * each registered token the user should provide, as well as the amount of protocol fees the Pool owes to the Vault.
     * The Vault will then take tokens from `sender` and add them to the Pool's balances, as well as collect
     * the reported amount in protocol fees, which the pool should calculate based on `protocolSwapFeePercentage`.
     *
     * Protocol fees are reported and charged on join events so that the Pool is free of debt whenever new users join.
     *
     * `sender` is the account performing the join (from which tokens will be withdrawn), and `recipient` is the account
     * designated to receive any benefits (typically pool shares). `balances` contains the total balances
     * for each token the Pool registered in the Vault, in the same order that `IVault.getPoolTokens` would return.
     *
     * `lastChangeBlock` is the last block in which *any* of the Pool's registered tokens last changed its total
     * balance.
     *
     * `userData` contains any pool-specific instructions needed to perform the calculations, such as the type of
     * join (e.g., proportional given an amount of pool shares, single-asset, multi-asset, etc.)
     *
     * Contracts implementing this function should check that the caller is indeed the Vault before performing any
     * state-changing operations, such as minting pool shares.
     */
    function onJoinPool(
        bytes32 poolId,
        address sender,
        address recipient,
        uint256[] memory balances,
        uint256 lastChangeBlock,
        uint256 protocolSwapFeePercentage,
        bytes memory userData
    ) external returns (uint256[] memory amountsIn, uint256[] memory dueProtocolFeeAmounts);

    /**
     * @dev Called by the Vault when a user calls `IVault.exitPool` to remove liquidity from this Pool. Returns how many
     * tokens the Vault should deduct from the Pool's balances, as well as the amount of protocol fees the Pool owes
     * to the Vault. The Vault will then take tokens from the Pool's balances and send them to `recipient`,
     * as well as collect the reported amount in protocol fees, which the Pool should calculate based on
     * `protocolSwapFeePercentage`.
     *
     * Protocol fees are charged on exit events to guarantee that users exiting the Pool have paid their share.
     *
     * `sender` is the account performing the exit (typically the pool shareholder), and `recipient` is the account
     * to which the Vault will send the proceeds. `balances` contains the total token balances for each token
     * the Pool registered in the Vault, in the same order that `IVault.getPoolTokens` would return.
     *
     * `lastChangeBlock` is the last block in which *any* of the Pool's registered tokens last changed its total
     * balance.
     *
     * `userData` contains any pool-specific instructions needed to perform the calculations, such as the type of
     * exit (e.g., proportional given an amount of pool shares, single-asset, multi-asset, etc.)
     *
     * Contracts implementing this function should check that the caller is indeed the Vault before performing any
     * state-changing operations, such as burning pool shares.
     */
    function onExitPool(
        bytes32 poolId,
        address sender,
        address recipient,
        uint256[] memory balances,
        uint256 lastChangeBlock,
        uint256 protocolSwapFeePercentage,
        bytes memory userData
    ) external returns (uint256[] memory amountsOut, uint256[] memory dueProtocolFeeAmounts);

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

/**
 * @dev Pool contracts with the MinimalSwapInfo or TwoToken specialization settings should implement this interface.
 *
 * This is called by the Vault when a user calls `IVault.swap` or `IVault.batchSwap` to swap with this Pool.
 * Returns the number of tokens the Pool will grant to the user in a 'given in' swap, or that the user will grant
 * to the pool in a 'given out' swap.
 *
 * This can often be implemented by a `view` function, since many pricing algorithms don't need to track state
 * changes in swaps. However, contracts implementing this in non-view functions should check that the caller is
 * indeed the Vault.
 */
interface IMinimalSwapInfoPool is IBasePool {
    function onSwap(
        SwapRequest memory swapRequest,
        uint256 currentBalanceTokenIn,
        uint256 currentBalanceTokenOut
    ) external returns (uint256 amount);
}

interface IGeneralPool is IBasePool {
    function onSwap(
        SwapRequest memory swapRequest,
        uint256[] memory balances,
        uint256 indexIn,
        uint256 indexOut
    ) external returns (uint256 amount);
}

pragma solidity ^0.8.0;

interface IMasterChef {
    function poolLength() external view returns (uint256);
    function getMultiplier(uint256 _from, uint256 _to) external view returns (uint256);
    function pendingSpirit(uint256 _pid, address _user) external view returns (uint256);
    function massUpdatePools() external;
    function updatePool(uint256 _pid) external;
    function deposit(uint256 _pid, uint256 _amount) external;
    function withdraw(uint256 _pid, uint256 _amount) external;
    function userInfo(uint256 _pid, address _user) external view returns (uint256, uint256);
    function emergencyWithdraw(uint256 _pid, address _to) external;
}

interface IMasterChefv2 {
    function harvest(uint256 pid, address to) external;
    function withdrawAndHarvest(uint256 pid, uint256 amount, address to) external;
    function deposit(uint256 pid, uint256 amount, address to) external;
    function beets() external view returns (uint256);
}

/**
 * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero
 * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like
 * types.
 *
 * This concept is unrelated to a Pool's Asset Managers.
 */
interface IAsset {
    // solhint-disable-previous-line no-empty-blocks
}


/**
 * @dev Interface for the SignatureValidator helper, used to support meta-transactions.
 */
interface ISignaturesValidator {
    /**
     * @dev Returns the EIP712 domain separator.
     */
    function getDomainSeparator() external view returns (bytes32);

    /**
     * @dev Returns the next nonce used by an address to sign messages.
     */
    function getNextNonce(address user) external view returns (uint256);
}

interface ITemporarilyPausable {
    /**
     * @dev Emitted every time the pause state changes by `_setPaused`.
     */
    event PausedStateChanged(bool paused);

    /**
     * @dev Returns the current paused state.
     */
    function getPausedState()
        external
        view
        returns (
            bool paused,
            uint256 pauseWindowEndTime,
            uint256 bufferPeriodEndTime
        );
}

pragma solidity ^0.8.0;


interface IVault is ISignaturesValidator, ITemporarilyPausable {
    // Generalities about the Vault:
    //
    // - Whenever documentation refers to 'tokens', it strictly refers to ERC20-compliant token contracts. Tokens are
    // transferred out of the Vault by calling the `IERC20.transfer` function, and transferred in by calling
    // `IERC20.transferFrom`. In these cases, the sender must have previously allowed the Vault to use their tokens by
    // calling `IERC20.approve`. The only deviation from the ERC20 standard that is supported is functions not returning
    // a boolean value: in these scenarios, a non-reverting call is assumed to be successful.
    //
    // - All non-view functions in the Vault are non-reentrant: calling them while another one is mid-execution (e.g.
    // while execution control is transferred to a token contract during a swap) will result in a revert. View
    // functions can be called in a re-reentrant way, but doing so might cause them to return inconsistent results.
    // Contracts calling view functions in the Vault must make sure the Vault has not already been entered.
    //
    // - View functions revert if referring to either unregistered Pools, or unregistered tokens for registered Pools.

    // Authorizer
    //
    // Some system actions are permissioned, like setting and collecting protocol fees. This permissioning system exists
    // outside of the Vault in the Authorizer contract: the Vault simply calls the Authorizer to check if the caller
    // can perform a given action.

    /**
     * @dev Returns the Vault's Authorizer.
     */
    function getAuthorizer() external view returns (IAuthorizer);

    /**
     * @dev Sets a new Authorizer for the Vault. The caller must be allowed by the current Authorizer to do this.
     *
     * Emits an `AuthorizerChanged` event.
     */
    function setAuthorizer(IAuthorizer newAuthorizer) external;

    /**
     * @dev Emitted when a new authorizer is set by `setAuthorizer`.
     */
    event AuthorizerChanged(IAuthorizer indexed newAuthorizer);

    // Relayers
    //
    // Additionally, it is possible for an account to perform certain actions on behalf of another one, using their
    // Vault ERC20 allowance and Internal Balance. These accounts are said to be 'relayers' for these Vault functions,
    // and are expected to be smart contracts with sound authentication mechanisms. For an account to be able to wield
    // this power, two things must occur:
    //  - The Authorizer must grant the account the permission to be a relayer for the relevant Vault function. This
    //    means that Balancer governance must approve each individual contract to act as a relayer for the intended
    //    functions.
    //  - Each user must approve the relayer to act on their behalf.
    // This double protection means users cannot be tricked into approving malicious relayers (because they will not
    // have been allowed by the Authorizer via governance), nor can malicious relayers approved by a compromised
    // Authorizer or governance drain user funds, since they would also need to be approved by each individual user.

    /**
     * @dev Returns true if `user` has approved `relayer` to act as a relayer for them.
     */
    function hasApprovedRelayer(address user, address relayer) external view returns (bool);

    /**
     * @dev Allows `relayer` to act as a relayer for `sender` if `approved` is true, and disallows it otherwise.
     *
     * Emits a `RelayerApprovalChanged` event.
     */
    function setRelayerApproval(
        address sender,
        address relayer,
        bool approved
    ) external;

    /**
     * @dev Emitted every time a relayer is approved or disapproved by `setRelayerApproval`.
     */
    event RelayerApprovalChanged(address indexed relayer, address indexed sender, bool approved);

    // Internal Balance
    //
    // Users can deposit tokens into the Vault, where they are allocated to their Internal Balance, and later
    // transferred or withdrawn. It can also be used as a source of tokens when joining Pools, as a destination
    // when exiting them, and as either when performing swaps. This usage of Internal Balance results in greatly reduced
    // gas costs when compared to relying on plain ERC20 transfers, leading to large savings for frequent users.
    //
    // Internal Balance management features batching, which means a single contract call can be used to perform multiple
    // operations of different kinds, with different senders and recipients, at once.

    /**
     * @dev Returns `user`'s Internal Balance for a set of tokens.
     */
    function getInternalBalance(address user, IERC20[] memory tokens) external view returns (uint256[] memory);

    /**
     * @dev Performs a set of user balance operations, which involve Internal Balance (deposit, withdraw or transfer)
     * and plain ERC20 transfers using the Vault's allowance. This last feature is particularly useful for relayers, as
     * it lets integrators reuse a user's Vault allowance.
     *
     * For each operation, if the caller is not `sender`, it must be an authorized relayer for them.
     */
    function manageUserBalance(UserBalanceOp[] memory ops) external payable;

    /**
     * @dev Data for `manageUserBalance` operations, which include the possibility for ETH to be sent and received
     without manual WETH wrapping or unwrapping.
     */
    struct UserBalanceOp {
        UserBalanceOpKind kind;
        IAsset asset;
        uint256 amount;
        address sender;
        address payable recipient;
    }

    // There are four possible operations in `manageUserBalance`:
    //
    // - DEPOSIT_INTERNAL
    // Increases the Internal Balance of the `recipient` account by transferring tokens from the corresponding
    // `sender`. The sender must have allowed the Vault to use their tokens via `IERC20.approve()`.
    //
    // ETH can be used by passing the ETH sentinel value as the asset and forwarding ETH in the call: it will be wrapped
    // and deposited as WETH. Any ETH amount remaining will be sent back to the caller (not the sender, which is
    // relevant for relayers).
    //
    // Emits an `InternalBalanceChanged` event.
    //
    //
    // - WITHDRAW_INTERNAL
    // Decreases the Internal Balance of the `sender` account by transferring tokens to the `recipient`.
    //
    // ETH can be used by passing the ETH sentinel value as the asset. This will deduct WETH instead, unwrap it and send
    // it to the recipient as ETH.
    //
    // Emits an `InternalBalanceChanged` event.
    //
    //
    // - TRANSFER_INTERNAL
    // Transfers tokens from the Internal Balance of the `sender` account to the Internal Balance of `recipient`.
    //
    // Reverts if the ETH sentinel value is passed.
    //
    // Emits an `InternalBalanceChanged` event.
    //
    //
    // - TRANSFER_EXTERNAL
    // Transfers tokens from `sender` to `recipient`, using the Vault's ERC20 allowance. This is typically used by
    // relayers, as it lets them reuse a user's Vault allowance.
    //
    // Reverts if the ETH sentinel value is passed.
    //
    // Emits an `ExternalBalanceTransfer` event.

    enum UserBalanceOpKind { DEPOSIT_INTERNAL, WITHDRAW_INTERNAL, TRANSFER_INTERNAL, TRANSFER_EXTERNAL }

    /**
     * @dev Emitted when a user's Internal Balance changes, either from calls to `manageUserBalance`, or through
     * interacting with Pools using Internal Balance.
     *
     * Because Internal Balance works exclusively with ERC20 tokens, ETH deposits and withdrawals will use the WETH
     * address.
     */
    event InternalBalanceChanged(address indexed user, IERC20 indexed token, int256 delta);

    /**
     * @dev Emitted when a user's Vault ERC20 allowance is used by the Vault to transfer tokens to an external account.
     */
    event ExternalBalanceTransfer(IERC20 indexed token, address indexed sender, address recipient, uint256 amount);

    // Pools
    //
    // There are three specialization settings for Pools, which allow for cheaper swaps at the cost of reduced
    // functionality:
    //
    //  - General: no specialization, suited for all Pools. IGeneralPool is used for swap request callbacks, passing the
    // balance of all tokens in the Pool. These Pools have the largest swap costs (because of the extra storage reads),
    // which increase with the number of registered tokens.
    //
    //  - Minimal Swap Info: IMinimalSwapInfoPool is used instead of IGeneralPool, which saves gas by only passing the
    // balance of the two tokens involved in the swap. This is suitable for some pricing algorithms, like the weighted
    // constant product one popularized by Balancer V1. Swap costs are smaller compared to general Pools, and are
    // independent of the number of registered tokens.
    //
    //  - Two Token: only allows two tokens to be registered. This achieves the lowest possible swap gas cost. Like
    // minimal swap info Pools, these are called via IMinimalSwapInfoPool.

    enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN }

    /**
     * @dev Registers the caller account as a Pool with a given specialization setting. Returns the Pool's ID, which
     * is used in all Pool-related functions. Pools cannot be deregistered, nor can the Pool's specialization be
     * changed.
     *
     * The caller is expected to be a smart contract that implements either `IGeneralPool` or `IMinimalSwapInfoPool`,
     * depending on the chosen specialization setting. This contract is known as the Pool's contract.
     *
     * Note that the same contract may register itself as multiple Pools with unique Pool IDs, or in other words,
     * multiple Pools may share the same contract.
     *
     * Emits a `PoolRegistered` event.
     */
    function registerPool(PoolSpecialization specialization) external returns (bytes32);

    /**
     * @dev Emitted when a Pool is registered by calling `registerPool`.
     */
    event PoolRegistered(bytes32 indexed poolId, address indexed poolAddress, PoolSpecialization specialization);

    /**
     * @dev Returns a Pool's contract address and specialization setting.
     */
    function getPool(bytes32 poolId) external view returns (address, PoolSpecialization);

    /**
     * @dev Registers `tokens` for the `poolId` Pool. Must be called by the Pool's contract.
     *
     * Pools can only interact with tokens they have registered. Users join a Pool by transferring registered tokens,
     * exit by receiving registered tokens, and can only swap registered tokens.
     *
     * Each token can only be registered once. For Pools with the Two Token specialization, `tokens` must have a length
     * of two, that is, both tokens must be registered in the same `registerTokens` call, and they must be sorted in
     * ascending order.
     *
     * The `tokens` and `assetManagers` arrays must have the same length, and each entry in these indicates the Asset
     * Manager for the corresponding token. Asset Managers can manage a Pool's tokens via `managePoolBalance`,
     * depositing and withdrawing them directly, and can even set their balance to arbitrary amounts. They are therefore
     * expected to be highly secured smart contracts with sound design principles, and the decision to register an
     * Asset Manager should not be made lightly.
     *
     * Pools can choose not to assign an Asset Manager to a given token by passing in the zero address. Once an Asset
     * Manager is set, it cannot be changed except by deregistering the associated token and registering again with a
     * different Asset Manager.
     *
     * Emits a `TokensRegistered` event.
     */
    function registerTokens(
        bytes32 poolId,
        IERC20[] memory tokens,
        address[] memory assetManagers
    ) external;

    /**
     * @dev Emitted when a Pool registers tokens by calling `registerTokens`.
     */
    event TokensRegistered(bytes32 indexed poolId, IERC20[] tokens, address[] assetManagers);

    /**
     * @dev Deregisters `tokens` for the `poolId` Pool. Must be called by the Pool's contract.
     *
     * Only registered tokens (via `registerTokens`) can be deregistered. Additionally, they must have zero total
     * balance. For Pools with the Two Token specialization, `tokens` must have a length of two, that is, both tokens
     * must be deregistered in the same `deregisterTokens` call.
     *
     * A deregistered token can be re-registered later on, possibly with a different Asset Manager.
     *
     * Emits a `TokensDeregistered` event.
     */
    function deregisterTokens(bytes32 poolId, IERC20[] memory tokens) external;

    /**
     * @dev Emitted when a Pool deregisters tokens by calling `deregisterTokens`.
     */
    event TokensDeregistered(bytes32 indexed poolId, IERC20[] tokens);

    /**
     * @dev Returns detailed information for a Pool's registered token.
     *
     * `cash` is the number of tokens the Vault currently holds for the Pool. `managed` is the number of tokens
     * withdrawn and held outside the Vault by the Pool's token Asset Manager. The Pool's total balance for `token`
     * equals the sum of `cash` and `managed`.
     *
     * Internally, `cash` and `managed` are stored using 112 bits. No action can ever cause a Pool's token `cash`,
     * `managed` or `total` balance to be greater than 2^112 - 1.
     *
     * `lastChangeBlock` is the number of the block in which `token`'s total balance was last modified (via either a
     * join, exit, swap, or Asset Manager update). This value is useful to avoid so-called 'sandwich attacks', for
     * example when developing price oracles. A change of zero (e.g. caused by a swap with amount zero) is considered a
     * change for this purpose, and will update `lastChangeBlock`.
     *
     * `assetManager` is the Pool's token Asset Manager.
     */
    function getPoolTokenInfo(bytes32 poolId, IERC20 token)
        external
        view
        returns (
            uint256 cash,
            uint256 managed,
            uint256 lastChangeBlock,
            address assetManager
        );

    /**
     * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of
     * the tokens' `balances` changed.
     *
     * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all
     * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order.
     *
     * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same
     * order as passed to `registerTokens`.
     *
     * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are
     * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo`
     * instead.
     */
    function getPoolTokens(bytes32 poolId)
        external
        view
        returns (
            IERC20[] memory tokens,
            uint256[] memory balances,
            uint256 lastChangeBlock
        );

    /**
     * @dev Called by users to join a Pool, which transfers tokens from `sender` into the Pool's balance. This will
     * trigger custom Pool behavior, which will typically grant something in return to `recipient` - often tokenized
     * Pool shares.
     *
     * If the caller is not `sender`, it must be an authorized relayer for them.
     *
     * The `assets` and `maxAmountsIn` arrays must have the same length, and each entry indicates the maximum amount
     * to send for each asset. The amounts to send are decided by the Pool and not the Vault: it just enforces
     * these maximums.
     *
     * If joining a Pool that holds WETH, it is possible to send ETH directly: the Vault will do the wrapping. To enable
     * this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead of the
     * WETH address. Note that it is not possible to combine ETH and WETH in the same join. Any excess ETH will be sent
     * back to the caller (not the sender, which is important for relayers).
     *
     * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when
     * interacting with Pools that register and deregister tokens frequently. If sending ETH however, the array must be
     * sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the final
     * `assets` array might not be sorted. Pools with no registered tokens cannot be joined.
     *
     * If `fromInternalBalance` is true, the caller's Internal Balance will be preferred: ERC20 transfers will only
     * be made for the difference between the requested amount and Internal Balance (if any). Note that ETH cannot be
     * withdrawn from Internal Balance: attempting to do so will trigger a revert.
     *
     * This causes the Vault to call the `IBasePool.onJoinPool` hook on the Pool's contract, where Pools implement
     * their own custom logic. This typically requires additional information from the user (such as the expected number
     * of Pool shares). This can be encoded in the `userData` argument, which is ignored by the Vault and passed
     * directly to the Pool's contract, as is `recipient`.
     *
     * Emits a `PoolBalanceChanged` event.
     */
    function joinPool(
        bytes32 poolId,
        address sender,
        address recipient,
        JoinPoolRequest memory request
    ) external payable;

    struct JoinPoolRequest {
        IAsset[] assets;
        uint256[] maxAmountsIn;
        bytes userData;
        bool fromInternalBalance;
    }

    /**
     * @dev Called by users to exit a Pool, which transfers tokens from the Pool's balance to `recipient`. This will
     * trigger custom Pool behavior, which will typically ask for something in return from `sender` - often tokenized
     * Pool shares. The amount of tokens that can be withdrawn is limited by the Pool's `cash` balance (see
     * `getPoolTokenInfo`).
     *
     * If the caller is not `sender`, it must be an authorized relayer for them.
     *
     * The `tokens` and `minAmountsOut` arrays must have the same length, and each entry in these indicates the minimum
     * token amount to receive for each token contract. The amounts to send are decided by the Pool and not the Vault:
     * it just enforces these minimums.
     *
     * If exiting a Pool that holds WETH, it is possible to receive ETH directly: the Vault will do the unwrapping. To
     * enable this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead
     * of the WETH address. Note that it is not possible to combine ETH and WETH in the same exit.
     *
     * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when
     * interacting with Pools that register and deregister tokens frequently. If receiving ETH however, the array must
     * be sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the
     * final `assets` array might not be sorted. Pools with no registered tokens cannot be exited.
     *
     * If `toInternalBalance` is true, the tokens will be deposited to `recipient`'s Internal Balance. Otherwise,
     * an ERC20 transfer will be performed. Note that ETH cannot be deposited to Internal Balance: attempting to
     * do so will trigger a revert.
     *
     * `minAmountsOut` is the minimum amount of tokens the user expects to get out of the Pool, for each token in the
     * `tokens` array. This array must match the Pool's registered tokens.
     *
     * This causes the Vault to call the `IBasePool.onExitPool` hook on the Pool's contract, where Pools implement
     * their own custom logic. This typically requires additional information from the user (such as the expected number
     * of Pool shares to return). This can be encoded in the `userData` argument, which is ignored by the Vault and
     * passed directly to the Pool's contract.
     *
     * Emits a `PoolBalanceChanged` event.
     */
    function exitPool(
        bytes32 poolId,
        address sender,
        address payable recipient,
        ExitPoolRequest memory request
    ) external;

    struct ExitPoolRequest {
        IAsset[] assets;
        uint256[] minAmountsOut;
        bytes userData;
        bool toInternalBalance;
    }

    /**
     * @dev Emitted when a user joins or exits a Pool by calling `joinPool` or `exitPool`, respectively.
     */
    event PoolBalanceChanged(
        bytes32 indexed poolId,
        address indexed liquidityProvider,
        IERC20[] tokens,
        int256[] deltas,
        uint256[] protocolFeeAmounts
    );

    enum PoolBalanceChangeKind { JOIN, EXIT }

    // Swaps
    //
    // Users can swap tokens with Pools by calling the `swap` and `batchSwap` functions. To do this,
    // they need not trust Pool contracts in any way: all security checks are made by the Vault. They must however be
    // aware of the Pools' pricing algorithms in order to estimate the prices Pools will quote.
    //
    // The `swap` function executes a single swap, while `batchSwap` can perform multiple swaps in sequence.
    // In each individual swap, tokens of one kind are sent from the sender to the Pool (this is the 'token in'),
    // and tokens of another kind are sent from the Pool to the recipient in exchange (this is the 'token out').
    // More complex swaps, such as one token in to multiple tokens out can be achieved by batching together
    // individual swaps.
    //
    // There are two swap kinds:
    //  - 'given in' swaps, where the amount of tokens in (sent to the Pool) is known, and the Pool determines (via the
    // `onSwap` hook) the amount of tokens out (to send to the recipient).
    //  - 'given out' swaps, where the amount of tokens out (received from the Pool) is known, and the Pool determines
    // (via the `onSwap` hook) the amount of tokens in (to receive from the sender).
    //
    // Additionally, it is possible to chain swaps using a placeholder input amount, which the Vault replaces with
    // the calculated output of the previous swap. If the previous swap was 'given in', this will be the calculated
    // tokenOut amount. If the previous swap was 'given out', it will use the calculated tokenIn amount. These extended
    // swaps are known as 'multihop' swaps, since they 'hop' through a number of intermediate tokens before arriving at
    // the final intended token.
    //
    // In all cases, tokens are only transferred in and out of the Vault (or withdrawn from and deposited into Internal
    // Balance) after all individual swaps have been completed, and the net token balance change computed. This makes
    // certain swap patterns, such as multihops, or swaps that interact with the same token pair in multiple Pools, cost
    // much less gas than they would otherwise.
    //
    // It also means that under certain conditions it is possible to perform arbitrage by swapping with multiple
    // Pools in a way that results in net token movement out of the Vault (profit), with no tokens being sent in (only
    // updating the Pool's internal accounting).
    //
    // To protect users from front-running or the market changing rapidly, they supply a list of 'limits' for each token
    // involved in the swap, where either the maximum number of tokens to send (by passing a positive value) or the
    // minimum amount of tokens to receive (by passing a negative value) is specified.
    //
    // Additionally, a 'deadline' timestamp can also be provided, forcing the swap to fail if it occurs after
    // this point in time (e.g. if the transaction failed to be included in a block promptly).
    //
    // If interacting with Pools that hold WETH, it is possible to both send and receive ETH directly: the Vault will do
    // the wrapping and unwrapping. To enable this mechanism, the IAsset sentinel value (the zero address) must be
    // passed in the `assets` array instead of the WETH address. Note that it is possible to combine ETH and WETH in the
    // same swap. Any excess ETH will be sent back to the caller (not the sender, which is relevant for relayers).
    //
    // Finally, Internal Balance can be used when either sending or receiving tokens.

    enum SwapKind { GIVEN_IN, GIVEN_OUT }

    /**
     * @dev Performs a swap with a single Pool.
     *
     * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens
     * taken from the Pool, which must be greater than or equal to `limit`.
     *
     * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens
     * sent to the Pool, which must be less than or equal to `limit`.
     *
     * Internal Balance usage and the recipient are determined by the `funds` struct.
     *
     * Emits a `Swap` event.
     */
    function swap(
        SingleSwap memory singleSwap,
        FundManagement memory funds,
        uint256 limit,
        uint256 deadline
    ) external payable returns (uint256);

    /**
     * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on
     * the `kind` value.
     *
     * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address).
     * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault.
     *
     * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be
     * used to extend swap behavior.
     */
    struct SingleSwap {
        bytes32 poolId;
        SwapKind kind;
        IAsset assetIn;
        IAsset assetOut;
        uint256 amount;
        bytes userData;
    }

    /**
     * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either
     * the amount of tokens sent to or received from the Pool, depending on the `kind` value.
     *
     * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the
     * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at
     * the same index in the `assets` array.
     *
     * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a
     * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or
     * `amountOut` depending on the swap kind.
     *
     * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out
     * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal
     * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`.
     *
     * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses,
     * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and
     * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to
     * or unwrapped from WETH by the Vault.
     *
     * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies
     * the minimum or maximum amount of each token the vault is allowed to transfer.
     *
     * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the
     * equivalent `swap` call.
     *
     * Emits `Swap` events.
     */
    function batchSwap(
        SwapKind kind,
        BatchSwapStep[] memory swaps,
        IAsset[] memory assets,
        FundManagement memory funds,
        int256[] memory limits,
        uint256 deadline
    ) external payable returns (int256[] memory);

    /**
     * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the
     * `assets` array passed to that function, and ETH assets are converted to WETH.
     *
     * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out
     * from the previous swap, depending on the swap kind.
     *
     * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be
     * used to extend swap behavior.
     */
    struct BatchSwapStep {
        bytes32 poolId;
        uint256 assetInIndex;
        uint256 assetOutIndex;
        uint256 amount;
        bytes userData;
    }

    /**
     * @dev Emitted for each individual swap performed by `swap` or `batchSwap`.
     */
    event Swap(
        bytes32 indexed poolId,
        IERC20 indexed tokenIn,
        IERC20 indexed tokenOut,
        uint256 amountIn,
        uint256 amountOut
    );

    /**
     * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the
     * `recipient` account.
     *
     * If the caller is not `sender`, it must be an authorized relayer for them.
     *
     * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20
     * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender`
     * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of
     * `joinPool`.
     *
     * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of
     * transferred. This matches the behavior of `exitPool`.
     *
     * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a
     * revert.
     */
    struct FundManagement {
        address sender;
        bool fromInternalBalance;
        address payable recipient;
        bool toInternalBalance;
    }

    /**
     * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be
     * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result.
     *
     * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH)
     * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it
     * receives are the same that an equivalent `batchSwap` call would receive.
     *
     * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct.
     * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens,
     * approve them for the Vault, or even know a user's address.
     *
     * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute
     * eth_call instead of eth_sendTransaction.
     */
    function queryBatchSwap(
        SwapKind kind,
        BatchSwapStep[] memory swaps,
        IAsset[] memory assets,
        FundManagement memory funds
    ) external returns (int256[] memory assetDeltas);



    // Asset Management
    //
    // Each token registered for a Pool can be assigned an Asset Manager, which is able to freely withdraw the Pool's
    // tokens from the Vault, deposit them, or assign arbitrary values to its `managed` balance (see
    // `getPoolTokenInfo`). This makes them extremely powerful and dangerous. Even if an Asset Manager only directly
    // controls one of the tokens in a Pool, a malicious manager could set that token's balance to manipulate the
    // prices of the other tokens, and then drain the Pool with swaps. The risk of using Asset Managers is therefore
    // not constrained to the tokens they are managing, but extends to the entire Pool's holdings.
    //
    // However, a properly designed Asset Manager smart contract can be safely used for the Pool's benefit,
    // for example by lending unused tokens out for interest, or using them to participate in voting protocols.
    //
    // This concept is unrelated to the IAsset interface.

    /**
     * @dev Performs a set of Pool balance operations, which may be either withdrawals, deposits or updates.
     *
     * Pool Balance management features batching, which means a single contract call can be used to perform multiple
     * operations of different kinds, with different Pools and tokens, at once.
     *
     * For each operation, the caller must be registered as the Asset Manager for `token` in `poolId`.
     */
    function managePoolBalance(PoolBalanceOp[] memory ops) external;

    struct PoolBalanceOp {
        PoolBalanceOpKind kind;
        bytes32 poolId;
        IERC20 token;
        uint256 amount;
    }

    /**
     * Withdrawals decrease the Pool's cash, but increase its managed balance, leaving the total balance unchanged.
     *
     * Deposits increase the Pool's cash, but decrease its managed balance, leaving the total balance unchanged.
     *
     * Updates don't affect the Pool's cash balance, but because the managed balance changes, it does alter the total.
     * The external amount can be either increased or decreased by this call (i.e., reporting a gain or a loss).
     */
    enum PoolBalanceOpKind { WITHDRAW, DEPOSIT, UPDATE }

    /**
     * @dev Emitted when a Pool's token Asset Manager alters its balance via `managePoolBalance`.
     */
    event PoolBalanceManaged(
        bytes32 indexed poolId,
        address indexed assetManager,
        IERC20 indexed token,
        int256 cashDelta,
        int256 managedDelta
    );

    // Protocol Fees
    //
    // Some operations cause the Vault to collect tokens in the form of protocol fees, which can then be withdrawn by
    // permissioned accounts.
    //
    // There are two kinds of protocol fees:
    //
    //  - flash loan fees: charged on all flash loans, as a percentage of the amounts lent.
    //
    //  - swap fees: a percentage of the fees charged by Pools when performing swaps. For a number of reasons, including
    // swap gas costs and interface simplicity, protocol swap fees are not charged on each individual swap. Rather,
    // Pools are expected to keep track of how much they have charged in swap fees, and pay any outstanding debts to the
    // Vault when they are joined or exited. This prevents users from joining a Pool with unpaid debt, as well as
    // exiting a Pool in debt without first paying their share.

    /**
     * @dev Safety mechanism to pause most Vault operations in the event of an emergency - typically detection of an
     * error in some part of the system.
     *
     * The Vault can only be paused during an initial time period, after which pausing is forever disabled.
     *
     * While the contract is paused, the following features are disabled:
     * - depositing and transferring internal balance
     * - transferring external balance (using the Vault's allowance)
     * - swaps
     * - joining Pools
     * - Asset Manager interactions
     *
     * Internal Balance can still be withdrawn, and Pools exited.
     */
    function setPaused(bool paused) external;

    /**
     * @dev Returns the Vault's WETH instance.
     */
}

interface IBaseWeightedPool {

    enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT }
    enum ExitKind {
        EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,
        EXACT_BPT_IN_FOR_TOKENS_OUT,
        BPT_IN_FOR_EXACT_TOKENS_OUT,
        MANAGEMENT_FEE_TOKENS_OUT // for InvestmentPool
    }

    function getNormalizedWeights() external view returns (uint256[] memory);


}

interface IBeetsBar{
    function enter(uint256 amount) external;
    function leave(uint256 amount) external;
}

pragma solidity ^0.8.0;
/**
 * @dev Implementation of a strategy to get yields from farming LP Pools in SpookySwap.
 * SpookySwap is an automated market maker (“AMM”) that allows two tokens to be exchanged on Fantom's Opera Network.
 *
 * This strategy deposits whatever funds it receives from the vault into the selected masterChef pool.
 * rewards from providing liquidity are farmed every few minutes, sold and split 50/50.
 * The corresponding pair of assets are bought and more liquidity is added to the masterChef pool.
 *
 * Expect the amount of LP tokens you have to grow over time while you have assets deposit
 */
contract ReaperAutoCompoundBeethoven_fBEETS is Ownable, Pausable {
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;

    /**
     * @dev Tokens Used:
     * {wftm} - Required for liquidity routing when doing swaps.
     * {rewardToken} - Token generated by staking our funds.
     * {lpToken} - LP Token that the strategy maximizes.
     * {lpToken0, lpToken1} - Tokens that the strategy maximizes. IUniswapV2Pair tokens.
     */
    address public constant wftm = address(0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83);
    address public constant underlyingLP = address(0xcdE5a11a4ACB4eE4c805352Cec57E236bdBC3837);
    address public constant fBEETS = address(0xfcef8a994209d6916EB2C86cDD2AFD60Aa6F54b1);
    address public constant rewardToken = address(0xF24Bcf4d1e507740041C9cFd2DddB29585aDCe1e);// beets token
    address public constant BeetVault = address(0x20dd72Ed959b6147912C2e529F0a0C651c33c9ce);
    address public lpToken;

    uint8 public totalUnderlyingTokens;

    mapping(uint8 => bool) public isEmitting;
    bool public harvestOn = false;
    /**
     * @dev Third Party Contracts:
     * {router} - the router for target DEX
     * {masterChef} - masterChef contract
     * {poolId} - masterChef pool id
     */

    address public masterChef = address(0x8166994d9ebBe5829EC86Bd81258149B87faCfd3);
    uint public poolId;
    bytes32 public poolID_bytes;

    uint8 public beetsPosition = 0;
    uint8 public wftmPosition = 0;
    bool public beetsUnderlying = false;
    bool public wftmUnderlying = false;
    bytes32 public route_ID;
    bytes32 public constant wftmRoute_ID = 0xcde5a11a4acb4ee4c805352cec57e236bdbc3837000200000000000000000019;
    bool public secondReward = false;
    address public secondRewardToken;
    bytes32 public secondRewardRoute;


    /**
     * @dev Reaper Contracts:
     * {treasury} - Address of the Reaper treasury
     * {vault} - Address of the vault that controls the strategy's funds.
     */
    address public treasury;
    address public vault;

     /**
     * @dev Distribution of fees earned. This allocations relative to the % implemented on
     * Current implementation separates 5% for fees. Can be changed through the constructor
     * Inputs in constructor should be ratios between the Fee and Max Fee, divisble into percents by 10000
     *
     * {callFee} - Percent of the totalFee reserved for the harvester (1000 = 10% of total fee: 0.5% by default)
     * {treasuryFee} - Percent of the totalFee taken by maintainers of the software (9000 = 90% of total fee: 4.5% by default)
     * {securityFee} - Fee taxed when a user withdraws funds. Taken to prevent flash deposit/harvest attacks.
     * These funds are redistributed to stakers in the pool.
     *
     * {totalFee} - divided by 10,000 to determine the % fee. Set to 5% by default and
     * lowered as necessary to provide users with the most competitive APY.
     *
     * {MAX_FEE} - Maximum fee allowed by the strategy. Hard-capped at 5%.
     * {PERCENT_DIVISOR} - Constant used to safely calculate the correct percentages.
     */

    uint public callFee = 1000;
    uint public treasuryFee = 9000;
    uint public securityFee = 10;
    uint public totalFee = 450;
    uint constant public MAX_FEE = 500;
    uint constant  public PERCENT_DIVISOR = 10000;

    /**
     * @dev Routes we take to swap tokens using PanrewardTokenSwap.
     * {rewardTokenToWftmRoute} - Route we take to get from {rewardToken} into {wftm}.
     * {rewardTokenToLp0Route} - Route we take to get from {rewardToken} into {lpToken0}.
     * {rewardTokenToLp1Route} - Route we take to get from {rewardToken} into {lpToken1}.
     */

    mapping (uint8 => address) public LPs;

    /**
     * {StratHarvest} Event that is fired each time someone harvests the strat.
     * {TotalFeeUpdated} Event that is fired each time the total fee is updated.
     * {CallFeeUpdated} Event that is fired each time the call fee is updated.
     */
    event StratHarvest(address indexed harvester);
    event TotalFeeUpdated(uint newFee);
    event CallFeeUpdated(uint newCallFee, uint newTreasuryFee);

    /**
     * @dev Initializes the strategy. Sets parameters, saves routes, and gives allowances.
     * @notice see documentation for each variable above its respective declaration.
     */
    constructor (
      address _lpToken,
      uint _poolId,
      address _vault,
      address _treasury
    ) public {
        lpToken = _lpToken;
        poolId = _poolId;
        poolID_bytes = wftmRoute_ID;
        vault = _vault;
        treasury = _treasury;

        //gather underlying tokens
        //we're assuming we are dealing with the PoolTokens.sol for the interface
        IERC20[] memory _lps;

        (_lps,,) = IVault(BeetVault).getPoolTokens(poolID_bytes);
        totalUnderlyingTokens = uint8(_lps.length);

        for(uint8 i; i < _lps.length; i++){
            LPs[i] = address(_lps[i]);
            if(LPs[i] == wftm){
                wftmPosition = i;
                wftmUnderlying = true;
            }

            if(LPs[i] == rewardToken){
                beetsPosition = i;
                beetsUnderlying = true;
            }
        }

        _giveAllowances(); //this will also need work
    }

    /**
     * @dev Function that puts the funds to work.
     * It gets called whenever someone deposits in the strategy's vault contract.
     * It deposits {lpToken} in the masterChef to farm {rewardToken}
     */
    function deposit() public whenNotPaused onActionHarvest{
        uint256 pairBal = IERC20(lpToken).balanceOf(address(this));

        if (pairBal > 0) {
            IMasterChefv2(masterChef).deposit(poolId, pairBal, address(this));
        }
    }

    /**
     * @dev Withdraws funds and sents them back to the vault.
     * It withdraws {lpToken} from the masterChef.
     * The available {lpToken} minus fees is returned to the vault.
     */
    function withdraw(uint256 _amount) external onActionHarvest{
    require(msg.sender == vault, "!vault");

      uint256 pairBal = IERC20(lpToken).balanceOf(address(this));

      if (pairBal < _amount) {
        IMasterChefv2(masterChef).withdrawAndHarvest(poolId, _amount.sub(pairBal), address(this));
        pairBal = IERC20(lpToken).balanceOf(address(this));
      }

      if (pairBal > _amount) {
        pairBal = _amount;
      }
      uint256 withdrawFee = pairBal.mul(securityFee).div(PERCENT_DIVISOR);
      IERC20(lpToken).safeTransfer(vault, pairBal.sub(withdrawFee));
    }


    /**
     * @dev Core function of the strat, in charge of collecting and re-investing rewards.
     * 1. It claims rewards from the masterChef.
     * 2. It charges the system fees to simplify the split.
     * 3. It swaps the {rewardToken} token for {lpToken0} & {lpToken1}
     * 4. Adds more liquidity to the pool.
     * 5. It deposits the new LP tokens.
     */
    function harvest() public whenNotPaused {
        require(!Address.isContract(msg.sender), "!contract");
        IMasterChefv2(masterChef).harvest(poolId, address(this));
        _chargeFees();

        if(secondReward){_swapSecondToken(secondRewardToken, secondRewardRoute);}

        _addLiquidity(rewardToken, beetsPosition);

        _enterX();

        deposit();

        emit StratHarvest(msg.sender);
    }

    function _enterX() internal {
        uint256 amtLP = IERC20(underlyingLP).balanceOf(address(this));
        IBeetsBar(fBEETS).enter(amtLP);
    }

    /**
     * @dev Takes out fees from the rewards. Set by constructor
     * callFeeToUser is set as a percentage of the fee,
     * as is treasuryFeeToVault
     */
    function _chargeFees() internal {
        uint256 rewardBal = IERC20(rewardToken).balanceOf(address(this));
        uint256 wftmBal = IERC20(wftm).balanceOf(address(this));

        uint256 fees;
        uint256 wftmFees;

        

        fees = rewardBal.mul(totalFee).div(PERCENT_DIVISOR);
        _swap(rewardToken, wftm, wftmRoute_ID, fees);
        wftmFees = IERC20(wftm).balanceOf(address(this)).sub(wftmBal);

        uint256 callFeeToUser = wftmFees.mul(callFee).div(PERCENT_DIVISOR);
        IERC20(wftm).safeTransfer(msg.sender, callFeeToUser);


        uint256 treasuryFeeToVault = wftmFees.mul(treasuryFee).div(PERCENT_DIVISOR);
        IERC20(wftm).safeTransfer(treasury, treasuryFeeToVault);

    }


    //function to swap from one token to another given a pool containing them both
    function _swap(address _tokenIN, address _tokenOUT, bytes32 _pool, uint256 amount) internal{

        IVault.SingleSwap memory singleSwap;
        IVault.SwapKind swapKind = IVault.SwapKind.GIVEN_IN;

        singleSwap.poolId = _pool;
        singleSwap.kind = swapKind;
        singleSwap.assetIn = IAsset(_tokenIN);
        singleSwap.assetOut = IAsset(_tokenOUT);
        singleSwap.amount = amount;
        singleSwap.userData = abi.encode(0);

        IVault.FundManagement memory funds;
        funds.sender = address(this);
        funds.fromInternalBalance = false;
        funds.recipient = payable(address(this));
        funds.toInternalBalance = false;

        IERC20(_tokenIN).safeApprove(BeetVault, 0);
        IERC20(_tokenIN).safeApprove(BeetVault, amount);

        IVault(BeetVault).swap(singleSwap, funds, 1, (block.timestamp + 600));

    }

    /**
     * @dev Swaps {rewardToken} for {lpToken0}, {lpToken1} & {wftm} using SpookySwap.
     */
    function _addLiquidity(address token, uint8 position) internal {
        uint256 depositTokenBalance = IERC20(token).balanceOf(address(this));

        IERC20(token).safeApprove(BeetVault, 0);
        IERC20(token).safeApprove(BeetVault, depositTokenBalance);

        IBaseWeightedPool.JoinKind joinKind = IBaseWeightedPool.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT;
        uint256[] memory amountsIn = new uint256[](totalUnderlyingTokens);
        amountsIn[position] = depositTokenBalance;
        uint256 minAmountOut = 1;
        IAsset[] memory _assets = new IAsset[](totalUnderlyingTokens);
        for(uint8 i = 0; i < totalUnderlyingTokens; i++){
            _assets[i] = IAsset(LPs[i]);
        }



        bytes memory userData = abi.encode(joinKind, amountsIn, minAmountOut);

        IVault.JoinPoolRequest memory request;
        request.assets = _assets;
        request.maxAmountsIn = amountsIn;
        request.userData = userData;
        request.fromInternalBalance = false;

        IVault(BeetVault).joinPool(
            poolID_bytes,
            address(this),
            address(this),
            request
        );
    }

    /**
     * @dev Function to calculate the total underlaying {lpToken} held by the strat.
     * It takes into account both the funds in hand, as the funds allocated in the masterChef.
     */
    function balanceOf() public view returns (uint256) {
        return balanceOfLpPair().add(balanceOfPool());
    }

    /**
     * @dev It calculates how much {lpToken} the contract holds.
     */
    function balanceOfLpPair() public view returns (uint256) {
        return IERC20(lpToken).balanceOf(address(this));
    }

    /**
     * @dev It calculates how much {lpToken} the strategy has allocated in the masterChef
     */
    function balanceOfPool() public view returns (uint256) {
        (uint256 _amount,) = IMasterChef(masterChef).userInfo(poolId, address(this));
        return _amount;
    }

    /**
     * @dev Function that has to be called as part of strat migration. It sends all the available funds back to the
     * vault, ready to be migrated to the new strat.
     */
    function retireStrat() external {
        require(msg.sender == vault, "!vault");

        IMasterChefv2(masterChef).withdrawAndHarvest(poolId, balanceOfPool(), address(this));

        uint256 pairBal = IERC20(lpToken).balanceOf(address(this));
        IERC20(lpToken).transfer(vault, pairBal);
    }

    /**
     * @dev Pauses deposits. Withdraws all funds from the masterChef, leaving rewards behind
     */
    function panic() public onlyOwner {
        pause();
        IMasterChef(masterChef).emergencyWithdraw(poolId, address(this));
    }

    /**
     * @dev Pauses the strat.
     */
    function pause() public onlyOwner {
      _pause();
      _removeAllowances();
    }

    /**
     * @dev Unpauses the strat.
     */
    function unpause() external onlyOwner {
        _unpause();

        _giveAllowances();

        deposit();
    }

    function _giveAllowances() internal {
        IERC20(underlyingLP).safeApprove(fBEETS, 0);
        IERC20(rewardToken).safeApprove(BeetVault, 0);
        IERC20(wftm).safeApprove(BeetVault, 0);
        IERC20(fBEETS).safeApprove(masterChef, 0);
        IERC20(underlyingLP).safeApprove(fBEETS, type(uint256).max);
        IERC20(rewardToken).safeApprove(BeetVault, type(uint256).max);
        IERC20(wftm).safeApprove(BeetVault, type(uint256).max);
        IERC20(fBEETS).safeApprove(masterChef, type(uint256).max);

    }

    function _removeAllowances() internal {
        IERC20(underlyingLP).safeApprove(fBEETS, 0);
        IERC20(rewardToken).safeApprove(BeetVault, 0);
        IERC20(wftm).safeApprove(BeetVault, 0);
        IERC20(fBEETS).safeApprove(masterChef, 0);
    }


    /**
     * @dev updates the total fee, capped at 5%
     */
    function updateTotalFee(uint _totalFee) external onlyOwner returns (bool) {
      require(_totalFee <= MAX_FEE, "Fee Too High");
      totalFee = _totalFee;
      emit TotalFeeUpdated(totalFee);
      return true;
    }

    /**
     * @dev updates the call fee and adjusts the treasury fee to cover the difference
     */
    function updateCallFee(uint _callFee) external onlyOwner returns (bool) {
      callFee = _callFee;
      treasuryFee = PERCENT_DIVISOR.sub(callFee);
      emit CallFeeUpdated(callFee, treasuryFee);
      return true;
    }

    function harvestOnAction(bool _setting) external onlyOwner returns (bool){
        harvestOn = _setting;
        return true;
    }


    modifier onActionHarvest {
        if (harvestOn == true){
            harvest();
        }
        _;
    }

    function updateRouteID(bytes32 newID) external onlyOwner {
        route_ID = newID;
    }

    function updateTreasury(address newTreasury) external onlyOwner returns (bool) {
      treasury = newTreasury;
      return true;
    }

    function _swapSecondToken(address token, bytes32 route) internal {

            uint256 wftmBal = IERC20(wftm).balanceOf(address(this));
            uint256 bal = IERC20(token).balanceOf(address(this));
            _swap(token, wftm, route, bal);
            uint256 fees = IERC20(wftm).balanceOf(address(this)).sub(wftmBal).mul(totalFee).div(PERCENT_DIVISOR);

            uint256 callFeeToUser = fees.mul(callFee).div(PERCENT_DIVISOR);
            IERC20(wftm).safeTransfer(msg.sender, callFeeToUser);

            uint256 treasuryFeeToVault = fees.mul(treasuryFee).div(PERCENT_DIVISOR);
            IERC20(wftm).safeTransfer(treasury, treasuryFeeToVault);

            
            wftmBal = IERC20(wftm).balanceOf(address(this));
            _swap(wftm, rewardToken, wftmRoute_ID, wftmBal);
            


    }

    // NOTE: this is a centralized, high trust function used to securely deliver a secondary reward payload to users in the vault
    // Please ensure anyone operating clones of this vault are trustworthy before putting your money in
    function secondRewardInformation(bool status, address token, bytes32 route) external onlyOwner {
        require(token != rewardToken, "rewardToken is already accounted for");
        secondReward = status;
        secondRewardToken = token;
        secondRewardRoute = route;
    }

    function updateSecurityFee(uint256 _fee) external onlyOwner {
        require(_fee <= 10, "fee too high");
        securityFee = _fee;
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCallFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTreasuryFee","type":"uint256"}],"name":"CallFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"harvester","type":"address"}],"name":"StratHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"TotalFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BeetVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"LPs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfLpPair","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beetsPosition","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beetsUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fBEETS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"harvestOnAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"isEmitting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterChef","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"panic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolID_bytes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"retireStrat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"route_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"route","type":"bytes32"}],"name":"secondRewardInformation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondRewardRoute","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondRewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"securityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnderlyingTokens","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlyingLP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_callFee","type":"uint256"}],"name":"updateCallFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newID","type":"bytes32"}],"name":"updateRouteID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"updateSecurityFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalFee","type":"uint256"}],"name":"updateTotalFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"updateTreasury","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftmPosition","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftmRoute_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftmUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600360006101000a81548160ff021916908315150217905550738166994d9ebbe5829ec86bd81258149b87facfd3600360016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600660006101000a81548160ff021916908360ff1602179055506000600660016101000a81548160ff021916908360ff1602179055506000600660026101000a81548160ff0219169083151502179055506000600660036101000a81548160ff0219169083151502179055506000600860006101000a81548160ff0219169083151502179055506103e8600c55612328600d55600a600e556101c2600f553480156200012157600080fd5b506040516200670d3803806200670d833981810160405281019062000147919062000f85565b620001676200015b6200059460201b60201c565b6200059c60201b60201c565b60008060146101000a81548160ff02191690831515021790555083600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826004819055507fcde5a11a4acb4ee4c805352cec57e236bdbc383700020000000000000000001960001b60058190555081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060607320dd72ed959b6147912c2e529f0a0c651c33c9ce73ffffffffffffffffffffffffffffffffffffffff1663f94d46686005546040518263ffffffff1660e01b8152600401620002c8919062001369565b60006040518083038186803b158015620002e157600080fd5b505afa158015620002f6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019062000321919062000ff1565b905050809150508051600160146101000a81548160ff021916908360ff16021790555060005b81518160ff1610156200057857818160ff168151811062000391577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151601060008360ff1660ff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff16601060008360ff1660ff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415620004a95780600660016101000a81548160ff021916908360ff1602179055506001600660036101000a81548160ff0219169083151502179055505b73f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff16601060008360ff1660ff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415620005625780600660006101000a81548160ff021916908360ff1602179055506001600660026101000a81548160ff0219169083151502179055505b80806200056f90620015a1565b91505062000347565b50620005896200066060201b60201c565b5050505050620016a7565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620006bb73fcef8a994209d6916eb2c86cdd2afd60aa6f54b1600073cde5a11a4acb4ee4c805352cec57e236bdbc383773ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b620007167320dd72ed959b6147912c2e529f0a0c651c33c9ce600073f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b620007717320dd72ed959b6147912c2e529f0a0c651c33c9ce60007321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b620007da600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600073fcef8a994209d6916eb2c86cdd2afd60aa6f54b173ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b6200085473fcef8a994209d6916eb2c86cdd2afd60aa6f54b17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73cde5a11a4acb4ee4c805352cec57e236bdbc383773ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b620008ce7320dd72ed959b6147912c2e529f0a0c651c33c9ce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b620009487320dd72ed959b6147912c2e529f0a0c651c33c9ce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b620009d0600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73fcef8a994209d6916eb2c86cdd2afd60aa6f54b173ffffffffffffffffffffffffffffffffffffffff16620009d260201b620020b1179092919060201c565b565b600081148062000a72575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b815260040162000a1c9291906200130f565b60206040518083038186803b15801562000a3557600080fd5b505afa15801562000a4a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a709190620010a5565b145b62000ab4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000aab9062001410565b60405180910390fd5b62000b3f8363095ea7b360e01b848460405160240162000ad69291906200133c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505062000b4460201b60201c565b505050565b600062000bad826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1662000c1860201b6200220f179092919060201c565b905060008151111562000c13578080602001905181019062000bd0919062001079565b62000c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000c0990620013ee565b60405180910390fd5b5b505050565b606062000c2f848460008562000c3860201b60201c565b90509392505050565b60608247101562000c80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000c7790620013aa565b60405180910390fd5b62000c918562000d6660201b60201c565b62000cd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000cca90620013cc565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162000cfe9190620012f6565b60006040518083038185875af1925050503d806000811462000d3d576040519150601f19603f3d011682016040523d82523d6000602084013e62000d42565b606091505b509150915062000d5a82828662000d7960201b60201c565b92505050949350505050565b600080823b905060008111915050919050565b6060831562000d8b5782905062000dde565b60008351111562000d9f5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000dd5919062001386565b60405180910390fd5b9392505050565b600062000dfc62000df68462001466565b62001432565b9050808382526020820190508285602086028201111562000e1c57600080fd5b60005b8581101562000e50578162000e35888262000f57565b84526020840193506020830192505060018101905062000e1f565b5050509392505050565b600062000e7162000e6b8462001495565b62001432565b9050808382526020820190508285602086028201111562000e9157600080fd5b60005b8581101562000ec5578162000eaa888262000f6e565b84526020840193506020830192505060018101905062000e94565b5050509392505050565b60008151905062000ee0816200163f565b92915050565b600082601f83011262000ef857600080fd5b815162000f0a84826020860162000de5565b91505092915050565b600082601f83011262000f2557600080fd5b815162000f3784826020860162000e5a565b91505092915050565b60008151905062000f518162001659565b92915050565b60008151905062000f688162001673565b92915050565b60008151905062000f7f816200168d565b92915050565b6000806000806080858703121562000f9c57600080fd5b600062000fac8782880162000ecf565b945050602062000fbf8782880162000f6e565b935050604062000fd28782880162000ecf565b925050606062000fe58782880162000ecf565b91505092959194509250565b6000806000606084860312156200100757600080fd5b600084015167ffffffffffffffff8111156200102257600080fd5b620010308682870162000ee6565b935050602084015167ffffffffffffffff8111156200104e57600080fd5b6200105c8682870162000f13565b92505060406200106f8682870162000f6e565b9150509250925092565b6000602082840312156200108c57600080fd5b60006200109c8482850162000f40565b91505092915050565b600060208284031215620010b857600080fd5b6000620010c88482850162000f6e565b91505092915050565b620010dc81620014f6565b82525050565b620010ed8162001516565b82525050565b60006200110082620014c4565b6200110c8185620014da565b93506200111e8185602086016200156b565b80840191505092915050565b60006200113782620014cf565b620011438185620014e5565b9350620011558185602086016200156b565b62001160816200162e565b840191505092915050565b60006200117a602683620014e5565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000620011e2601d83620014e5565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600062001224602a83620014e5565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b60006200128c603683620014e5565b91507f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008301527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006020830152604082019050919050565b620012f08162001554565b82525050565b6000620013048284620010f3565b915081905092915050565b6000604082019050620013266000830185620010d1565b620013356020830184620010d1565b9392505050565b6000604082019050620013536000830185620010d1565b620013626020830184620012e5565b9392505050565b6000602082019050620013806000830184620010e2565b92915050565b60006020820190508181036000830152620013a281846200112a565b905092915050565b60006020820190508181036000830152620013c5816200116b565b9050919050565b60006020820190508181036000830152620013e781620011d3565b9050919050565b60006020820190508181036000830152620014098162001215565b9050919050565b600060208201905081810360008301526200142b816200127d565b9050919050565b6000604051905081810181811067ffffffffffffffff821117156200145c576200145b620015ff565b5b8060405250919050565b600067ffffffffffffffff821115620014845762001483620015ff565b5b602082029050602081019050919050565b600067ffffffffffffffff821115620014b357620014b2620015ff565b5b602082029050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b6000620015038262001534565b9050919050565b60008115159050919050565b6000819050919050565b60006200152d82620014f6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156200158b5780820151818401526020810190506200156e565b838111156200159b576000848401525b50505050565b6000620015ae826200155e565b915060ff821415620015c557620015c4620015d0565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6200164a81620014f6565b81146200165657600080fd5b50565b62001664816200150a565b81146200167057600080fd5b50565b6200167e8162001520565b81146200168a57600080fd5b50565b620016988162001554565b8114620016a457600080fd5b50565b61505680620016b76000396000f3fe608060405234801561001057600080fd5b50600436106102f15760003560e01c80638da5cb5b1161019d578063d68e1302116100e9578063f7c618c1116100a2578063fb6177871161007c578063fb61778714610862578063fbfa77cf1461086c578063fec94ad11461088a578063ff08b97d146108a8576102f1565b8063f7c618c1146107e4578063f88fb68914610802578063f911545314610832576102f1565b8063d68e130214610734578063ec4942da14610752578063edf2d5d214610770578063f2fde38b1461078c578063f4f45b46146107a8578063f587cde9146107c6576102f1565b8063bdd3105811610156578063cc32d17611610130578063cc32d176146106be578063ced0883e146106dc578063d0e30db0146106fa578063d32b960414610704576102f1565b8063bdd3105814610666578063c2351cdd14610684578063c8212ce2146106a2576102f1565b80638da5cb5b146105a057806390321e1a146105be578063949c12c3146105dc5780639a111c371461060c578063aaf8561a1461062a578063bc063e1a14610648576102f1565b8063575a86b21161025c5780636f680bcf116102155780637380fa3f116101ef5780637380fa3f146105185780637f51bb1f146105365780638456cb59146105665780638954ffeb14610570576102f1565b80636f680bcf146104d2578063715018a6146104f0578063722713f7146104fa576102f1565b8063575a86b2146104205780635c975abb1461043e5780635fcbd2851461045c578063615911491461047a57806361d027b314610496578063635f91d0146104b4576102f1565b80633e0dc34e116102ae5780633e0dc34e146103a85780633e6b35cb146103c65780633f4ba83a146103e45780634641257d146103ee5780634700d305146103f85780634870dd9a14610402576102f1565b80630537524b146102f657806311588086146103145780631df4ccfc146103325780631eec4592146103505780632ae3af4b1461036e5780632e1a7d4d1461038c575b600080fd5b6102fe6108c6565b60405161030b9190614797565b60405180910390f35b61031c6108de565b6040516103299190614aed565b60405180910390f35b61033a610999565b6040516103479190614aed565b60405180910390f35b61035861099f565b604051610365919061481f565b60405180910390f35b6103766109c6565b604051610383919061481f565b60405180910390f35b6103a660048036038101906103a19190613eae565b6109cc565b005b6103b0610d4a565b6040516103bd9190614aed565b60405180910390f35b6103ce610d50565b6040516103db9190614b91565b60405180910390f35b6103ec610d63565b005b6103f6610df9565b005b610400610fe9565b005b61040a611100565b6040516104179190614aed565b60405180910390f35b610428611106565b6040516104359190614797565b60405180910390f35b61044661112c565b6040516104539190614804565b60405180910390f35b610464611142565b6040516104719190614797565b60405180910390f35b610494600480360381019061048f9190613eae565b611168565b005b61049e611232565b6040516104ab9190614797565b60405180910390f35b6104bc611258565b6040516104c9919061481f565b60405180910390f35b6104da61125e565b6040516104e79190614797565b60405180910390f35b6104f8611276565b005b6105026112fe565b60405161050f9190614aed565b60405180910390f35b610520611326565b60405161052d9190614797565b60405180910390f35b610550600480360381019061054b9190613dbb565b61133e565b60405161055d9190614804565b60405180910390f35b61056e611406565b005b61058a60048036038101906105859190613f3c565b611494565b6040516105979190614804565b60405180910390f35b6105a86114b4565b6040516105b59190614797565b60405180910390f35b6105c66114dd565b6040516105d39190614aed565b60405180910390f35b6105f660048036038101906105f19190613f3c565b6114e3565b6040516106039190614797565b60405180910390f35b610614611516565b6040516106219190614797565b60405180910390f35b61063261153c565b60405161063f9190614b91565b60405180910390f35b61065061154f565b60405161065d9190614aed565b60405180910390f35b61066e611555565b60405161067b919061481f565b60405180910390f35b61068c61155b565b6040516106999190614aed565b60405180910390f35b6106bc60048036038101906106b79190613e85565b61160d565b005b6106c6611693565b6040516106d39190614aed565b60405180910390f35b6106e4611699565b6040516106f19190614804565b60405180910390f35b6107026116ac565b005b61071e60048036038101906107199190613eae565b611868565b60405161072b9190614804565b60405180910390f35b61073c611974565b6040516107499190614aed565b60405180910390f35b61075a61197a565b6040516107679190614804565b60405180910390f35b61078a60048036038101906107859190613e36565b61198d565b005b6107a660048036038101906107a19190613dbb565b611af3565b005b6107b0611beb565b6040516107bd9190614797565b60405180910390f35b6107ce611c03565b6040516107db9190614b91565b60405180910390f35b6107ec611c16565b6040516107f99190614797565b60405180910390f35b61081c60048036038101906108179190613eae565b611c2e565b6040516108299190614804565b60405180910390f35b61084c60048036038101906108479190613de4565b611d16565b6040516108599190614804565b60405180910390f35b61086a611db7565b005b610874612065565b6040516108819190614797565b60405180910390f35b61089261208b565b60405161089f9190614804565b60405180910390f35b6108b061209e565b6040516108bd9190614804565b60405180910390f35b7320dd72ed959b6147912c2e529f0a0c651c33c9ce81565b600080600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393f1a40b600454306040518363ffffffff1660e01b8152600401610940929190614b08565b604080518083038186803b15801561095757600080fd5b505afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f9190613f00565b5090508091505090565b600f5481565b7fcde5a11a4acb4ee4c805352cec57e236bdbc383700020000000000000000001960001b81565b60095481565b60011515600360009054906101000a900460ff16151514156109f1576109f0610df9565b5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a78906149c1565b60405180910390fd5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ade9190614797565b60206040518083038186803b158015610af657600080fd5b505afa158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e9190613ed7565b905081811015610c8b57600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d1abb907600454610b8c848661222790919063ffffffff16565b306040518463ffffffff1660e01b8152600401610bab93929190614b5a565b600060405180830381600087803b158015610bc557600080fd5b505af1158015610bd9573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c389190614797565b60206040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c889190613ed7565b90505b81811115610c97578190505b6000610cc2612710610cb4600e548561223d90919063ffffffff16565b61225390919063ffffffff16565b9050610d45600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610cfd838561222790919063ffffffff16565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166122699092919063ffffffff16565b505050565b60045481565b600660019054906101000a900460ff1681565b610d6b6122ef565b73ffffffffffffffffffffffffffffffffffffffff16610d896114b4565b73ffffffffffffffffffffffffffffffffffffffff1614610ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd6906149e1565b60405180910390fd5b610de76122f7565b610def612398565b610df76116ac565b565b610e0161112c565b15610e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e38906149a1565b60405180910390fd5b610e4a336126d2565b15610e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8190614941565b60405180910390fd5b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318fccc76600454306040518363ffffffff1660e01b8152600401610ee9929190614b08565b600060405180830381600087803b158015610f0357600080fd5b505af1158015610f17573d6000803e3d6000fd5b50505050610f236126e5565b600860009054906101000a900460ff1615610f6757610f66600860019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600954612a5f565b5b610f9473f24bcf4d1e507740041c9cfd2dddb29585adce1e600660009054906101000a900460ff16612e81565b610f9c6132be565b610fa46116ac565b3373ffffffffffffffffffffffffffffffffffffffff167f577a37fdb49a88d66684922c6f913df5239b4f214b2b97c53ef8e3bbb2034cb560405160405180910390a2565b610ff16122ef565b73ffffffffffffffffffffffffffffffffffffffff1661100f6114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611065576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105c906149e1565b60405180910390fd5b61106d611406565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632f940c70600454306040518363ffffffff1660e01b81526004016110cc929190614b08565b600060405180830381600087803b1580156110e657600080fd5b505af11580156110fa573d6000803e3d6000fd5b50505050565b61271081565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060149054906101000a900460ff16905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6111706122ef565b73ffffffffffffffffffffffffffffffffffffffff1661118e6114b4565b73ffffffffffffffffffffffffffffffffffffffff16146111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db906149e1565b60405180910390fd5b600a811115611228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121f90614a01565b60405180910390fd5b80600e8190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075481565b73fcef8a994209d6916eb2c86cdd2afd60aa6f54b181565b61127e6122ef565b73ffffffffffffffffffffffffffffffffffffffff1661129c6114b4565b73ffffffffffffffffffffffffffffffffffffffff16146112f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e9906149e1565b60405180910390fd5b6112fc60006133e1565b565b600061132161130b6108de565b61131361155b565b6134a590919063ffffffff16565b905090565b73cde5a11a4acb4ee4c805352cec57e236bdbc383781565b60006113486122ef565b73ffffffffffffffffffffffffffffffffffffffff166113666114b4565b73ffffffffffffffffffffffffffffffffffffffff16146113bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b3906149e1565b60405180910390fd5b81600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b61140e6122ef565b73ffffffffffffffffffffffffffffffffffffffff1661142c6114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611482576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611479906149e1565b60405180910390fd5b61148a6134bb565b61149261355e565b565b60026020528060005260406000206000915054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600c5481565b60106020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160149054906101000a900460ff1681565b6101f481565b60055481565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016115b89190614797565b60206040518083038186803b1580156115d057600080fd5b505afa1580156115e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116089190613ed7565b905090565b6116156122ef565b73ffffffffffffffffffffffffffffffffffffffff166116336114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611689576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611680906149e1565b60405180910390fd5b8060078190555050565b600d5481565b600660029054906101000a900460ff1681565b6116b461112c565b156116f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116eb906149a1565b60405180910390fd5b60011515600360009054906101000a900460ff161515141561171957611718610df9565b5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016117769190614797565b60206040518083038186803b15801561178e57600080fd5b505afa1580156117a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c69190613ed7565b9050600081111561186557600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638dbdbe6d60045483306040518463ffffffff1660e01b815260040161183293929190614b5a565b600060405180830381600087803b15801561184c57600080fd5b505af1158015611860573d6000803e3d6000fd5b505050505b50565b60006118726122ef565b73ffffffffffffffffffffffffffffffffffffffff166118906114b4565b73ffffffffffffffffffffffffffffffffffffffff16146118e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118dd906149e1565b60405180910390fd5b6101f482111561192b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192290614a41565b60405180910390fd5b81600f819055507f2e59d502792bca3d730c472cd3acfbc16d0f9fe6ce0cddbdf0f80830251dfaca600f546040516119639190614aed565b60405180910390a160019050919050565b600e5481565b600360009054906101000a900460ff1681565b6119956122ef565b73ffffffffffffffffffffffffffffffffffffffff166119b36114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611a09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a00906149e1565b60405180910390fd5b73f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8390614961565b60405180910390fd5b82600860006101000a81548160ff02191690831515021790555081600860016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600981905550505050565b611afb6122ef565b73ffffffffffffffffffffffffffffffffffffffff16611b196114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b66906149e1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd690614921565b60405180910390fd5b611be8816133e1565b50565b7321be370d5312f44cb42ce377bc9b8a0cef1a4c8381565b600660009054906101000a900460ff1681565b73f24bcf4d1e507740041c9cfd2dddb29585adce1e81565b6000611c386122ef565b73ffffffffffffffffffffffffffffffffffffffff16611c566114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca3906149e1565b60405180910390fd5b81600c81905550611cca600c5461271061222790919063ffffffff16565b600d819055507f06a730aa61ec47f8cc95582be032daaf0ec4cb816c24b9c07b574ea41821048b600c54600d54604051611d05929190614b31565b60405180910390a160019050919050565b6000611d206122ef565b73ffffffffffffffffffffffffffffffffffffffff16611d3e6114b4565b73ffffffffffffffffffffffffffffffffffffffff1614611d94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8b906149e1565b60405180910390fd5b81600360006101000a81548160ff02191690831515021790555060019050919050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3e906149c1565b60405180910390fd5b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d1abb907600454611e906108de565b306040518463ffffffff1660e01b8152600401611eaf93929190614b5a565b600060405180830381600087803b158015611ec957600080fd5b505af1158015611edd573d6000803e3d6000fd5b505050506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611f3e9190614797565b60206040518083038186803b158015611f5657600080fd5b505afa158015611f6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8e9190613ed7565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b815260040161200f9291906147db565b602060405180830381600087803b15801561202957600080fd5b505af115801561203d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120619190613e0d565b5050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860009054906101000a900460ff1681565b600660039054906101000a900460ff1681565b600081148061214a575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b81526004016120f89291906147b2565b60206040518083038186803b15801561211057600080fd5b505afa158015612124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121489190613ed7565b145b612189576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218090614a81565b60405180910390fd5b61220a8363095ea7b360e01b84846040516024016121a89291906147db565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136be565b505050565b606061221e8484600085613785565b90509392505050565b600081836122359190614d53565b905092915050565b6000818361224b9190614cf9565b905092915050565b600081836122619190614cc8565b905092915050565b6122ea8363a9059cbb60e01b84846040516024016122889291906147db565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136be565b505050565b600033905090565b6122ff61112c565b61233e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233590614901565b60405180910390fd5b60008060146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6123816122ef565b60405161238e9190614797565b60405180910390a1565b6123ec73fcef8a994209d6916eb2c86cdd2afd60aa6f54b1600073cde5a11a4acb4ee4c805352cec57e236bdbc383773ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6124407320dd72ed959b6147912c2e529f0a0c651c33c9ce600073f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6124947320dd72ed959b6147912c2e529f0a0c651c33c9ce60007321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6124f6600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600073fcef8a994209d6916eb2c86cdd2afd60aa6f54b173ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b61256973fcef8a994209d6916eb2c86cdd2afd60aa6f54b17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73cde5a11a4acb4ee4c805352cec57e236bdbc383773ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6125dc7320dd72ed959b6147912c2e529f0a0c651c33c9ce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b61264f7320dd72ed959b6147912c2e529f0a0c651c33c9ce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6126d0600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73fcef8a994209d6916eb2c86cdd2afd60aa6f54b173ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b565b600080823b905060008111915050919050565b600073f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016127349190614797565b60206040518083038186803b15801561274c57600080fd5b505afa158015612760573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127849190613ed7565b905060007321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016127d59190614797565b60206040518083038186803b1580156127ed57600080fd5b505afa158015612801573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128259190613ed7565b9050600080612853612710612845600f548761223d90919063ffffffff16565b61225390919063ffffffff16565b91506128ac73f24bcf4d1e507740041c9cfd2dddb29585adce1e7321be370d5312f44cb42ce377bc9b8a0cef1a4c837fcde5a11a4acb4ee4c805352cec57e236bdbc383700020000000000000000001960001b85613899565b61295b837321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016128fd9190614797565b60206040518083038186803b15801561291557600080fd5b505afa158015612929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294d9190613ed7565b61222790919063ffffffff16565b9050600061298861271061297a600c548561223d90919063ffffffff16565b61225390919063ffffffff16565b90506129c933827321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166122699092919063ffffffff16565b60006129f46127106129e6600d548661223d90919063ffffffff16565b61225390919063ffffffff16565b9050612a57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16827321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166122699092919063ffffffff16565b505050505050565b60007321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612aae9190614797565b60206040518083038186803b158015612ac657600080fd5b505afa158015612ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612afe9190613ed7565b905060008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612b3b9190614797565b60206040518083038186803b158015612b5357600080fd5b505afa158015612b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8b9190613ed7565b9050612bad847321be370d5312f44cb42ce377bc9b8a0cef1a4c838584613899565b6000612c86612710612c78600f54612c6a877321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612c0c9190614797565b60206040518083038186803b158015612c2457600080fd5b505afa158015612c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5c9190613ed7565b61222790919063ffffffff16565b61223d90919063ffffffff16565b61225390919063ffffffff16565b90506000612cb3612710612ca5600c548561223d90919063ffffffff16565b61225390919063ffffffff16565b9050612cf433827321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166122699092919063ffffffff16565b6000612d1f612710612d11600d548661223d90919063ffffffff16565b61225390919063ffffffff16565b9050612d82600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16827321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166122699092919063ffffffff16565b7321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612dcf9190614797565b60206040518083038186803b158015612de757600080fd5b505afa158015612dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e1f9190613ed7565b9450612e787321be370d5312f44cb42ce377bc9b8a0cef1a4c8373f24bcf4d1e507740041c9cfd2dddb29585adce1e7fcde5a11a4acb4ee4c805352cec57e236bdbc383700020000000000000000001960001b88613899565b50505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612ebc9190614797565b60206040518083038186803b158015612ed457600080fd5b505afa158015612ee8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f0c9190613ed7565b9050612f4e7320dd72ed959b6147912c2e529f0a0c651c33c9ce60008573ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b612f8d7320dd72ed959b6147912c2e529f0a0c651c33c9ce828573ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6000600190506000600160149054906101000a900460ff1660ff1667ffffffffffffffff811115612fe7577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156130155781602001602082028036833780820191505090505b50905082818560ff1681518110613055577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250506000600190506000600160149054906101000a900460ff1660ff1667ffffffffffffffff8111156130bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156130e95781602001602082028036833780820191505090505b50905060005b600160149054906101000a900460ff1660ff168160ff1610156131cf57601060008260ff1660ff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828260ff1681518110613182577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806131c790614ebd565b9150506130ef565b5060008484846040516020016131e793929190614886565b6040516020818303038152906040529050613200613c09565b82816000018190525084816020018190525081816040018190525060008160600190151590811515815250507320dd72ed959b6147912c2e529f0a0c651c33c9ce73ffffffffffffffffffffffffffffffffffffffff1663b95cac286005543030856040518563ffffffff1660e01b8152600401613281949392919061483a565b600060405180830381600087803b15801561329b57600080fd5b505af11580156132af573d6000803e3d6000fd5b50505050505050505050505050565b600073cde5a11a4acb4ee4c805352cec57e236bdbc383773ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161330d9190614797565b60206040518083038186803b15801561332557600080fd5b505afa158015613339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335d9190613ed7565b905073fcef8a994209d6916eb2c86cdd2afd60aa6f54b173ffffffffffffffffffffffffffffffffffffffff1663a59f3e0c826040518263ffffffff1660e01b81526004016133ac9190614aed565b600060405180830381600087803b1580156133c657600080fd5b505af11580156133da573d6000803e3d6000fd5b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081836134b39190614c72565b905092915050565b6134c361112c565b15613503576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134fa906149a1565b60405180910390fd5b6001600060146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586135476122ef565b6040516135549190614797565b60405180910390a1565b6135b273fcef8a994209d6916eb2c86cdd2afd60aa6f54b1600073cde5a11a4acb4ee4c805352cec57e236bdbc383773ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6136067320dd72ed959b6147912c2e529f0a0c651c33c9ce600073f24bcf4d1e507740041c9cfd2dddb29585adce1e73ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b61365a7320dd72ed959b6147912c2e529f0a0c651c33c9ce60007321be370d5312f44cb42ce377bc9b8a0cef1a4c8373ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b6136bc600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600073fcef8a994209d6916eb2c86cdd2afd60aa6f54b173ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b565b6000613720826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661220f9092919063ffffffff16565b905060008151111561378057808060200190518101906137409190613e0d565b61377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690614a61565b60405180910390fd5b5b505050565b6060824710156137ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137c190614981565b60405180910390fd5b6137d3856126d2565b613812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380990614a21565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161383b9190614780565b60006040518083038185875af1925050503d8060008114613878576040519150601f19603f3d011682016040523d82523d6000602084013e61387d565b606091505b509150915061388d828286613ba2565b92505050949350505050565b6138a1613c33565b60008382600001818152505080826020019060018111156138eb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b90816001811115613925577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8152505085826040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084826060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508282608001818152505060006040516020016139b591906148c4565b6040516020818303038152906040528260a001819052506139d4613cd0565b30816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600081602001901515908115158152505030816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000816060019015159081151581525050613aa67320dd72ed959b6147912c2e529f0a0c651c33c9ce60008973ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b613ae57320dd72ed959b6147912c2e529f0a0c651c33c9ce858973ffffffffffffffffffffffffffffffffffffffff166120b19092919063ffffffff16565b7320dd72ed959b6147912c2e529f0a0c651c33c9ce73ffffffffffffffffffffffffffffffffffffffff166352bbbe298483600161025842613b279190614c72565b6040518563ffffffff1660e01b8152600401613b469493929190614aa1565b602060405180830381600087803b158015613b6057600080fd5b505af1158015613b74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b989190613ed7565b5050505050505050565b60608315613bb257829050613c02565b600083511115613bc55782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613bf991906148df565b60405180910390fd5b9392505050565b60405180608001604052806060815260200160608152602001606081526020016000151581525090565b6040518060c001604052806000801916815260200160006001811115613c82577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001606081525090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000151581525090565b600081359050613d3781614fad565b92915050565b600081359050613d4c81614fc4565b92915050565b600081519050613d6181614fc4565b92915050565b600081359050613d7681614fdb565b92915050565b600081359050613d8b81614ff2565b92915050565b600081519050613da081614ff2565b92915050565b600081359050613db581615009565b92915050565b600060208284031215613dcd57600080fd5b6000613ddb84828501613d28565b91505092915050565b600060208284031215613df657600080fd5b6000613e0484828501613d3d565b91505092915050565b600060208284031215613e1f57600080fd5b6000613e2d84828501613d52565b91505092915050565b600080600060608486031215613e4b57600080fd5b6000613e5986828701613d3d565b9350506020613e6a86828701613d28565b9250506040613e7b86828701613d67565b9150509250925092565b600060208284031215613e9757600080fd5b6000613ea584828501613d67565b91505092915050565b600060208284031215613ec057600080fd5b6000613ece84828501613d7c565b91505092915050565b600060208284031215613ee957600080fd5b6000613ef784828501613d91565b91505092915050565b60008060408385031215613f1357600080fd5b6000613f2185828601613d91565b9250506020613f3285828601613d91565b9150509250929050565b600060208284031215613f4e57600080fd5b6000613f5c84828501613da6565b91505092915050565b6000613f718383614182565b60208301905092915050565b6000613f898383614753565b60208301905092915050565b613f9e81614d99565b82525050565b613fad81614d87565b82525050565b613fbc81614d87565b82525050565b6000613fcd82614bcc565b613fd78185614c12565b9350613fe283614bac565b8060005b83811015614013578151613ffa8882613f65565b975061400583614bf8565b925050600181019050613fe6565b5085935050505092915050565b600061402b82614bd7565b6140358185614c23565b935061404083614bbc565b8060005b838110156140715781516140588882613f7d565b975061406383614c05565b925050600181019050614044565b5085935050505092915050565b600061408982614bd7565b6140938185614c34565b935061409e83614bbc565b8060005b838110156140cf5781516140b68882613f7d565b97506140c183614c05565b9250506001810190506140a2565b5085935050505092915050565b6140e581614dab565b82525050565b6140f481614dab565b82525050565b61410381614db7565b82525050565b61411281614db7565b82525050565b600061412382614be2565b61412d8185614c45565b935061413d818560208601614e8a565b61414681614f74565b840191505092915050565b600061415c82614be2565b6141668185614c56565b9350614176818560208601614e8a565b80840191505092915050565b61418b81614e1e565b82525050565b61419a81614e42565b82525050565b6141a981614e54565b82525050565b6141b881614e66565b82525050565b6141c781614e78565b82525050565b60006141d882614bed565b6141e28185614c61565b93506141f2818560208601614e8a565b6141fb81614f74565b840191505092915050565b6000614213601483614c61565b91507f5061757361626c653a206e6f74207061757365640000000000000000000000006000830152602082019050919050565b6000614253602683614c61565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006142b9600983614c61565b91507f21636f6e747261637400000000000000000000000000000000000000000000006000830152602082019050919050565b60006142f9602483614c61565b91507f726577617264546f6b656e20697320616c7265616479206163636f756e74656460008301527f20666f72000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061435f602683614c61565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006143c5601083614c61565b91507f5061757361626c653a20706175736564000000000000000000000000000000006000830152602082019050919050565b6000614405600683614c61565b91507f217661756c7400000000000000000000000000000000000000000000000000006000830152602082019050919050565b6000614445602083614c61565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000614485600c83614c61565b91507f66656520746f6f206869676800000000000000000000000000000000000000006000830152602082019050919050565b60006144c5601d83614c61565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000614505600c83614c61565b91507f46656520546f6f204869676800000000000000000000000000000000000000006000830152602082019050919050565b6000614545602a83614c61565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b60006145ab603683614c61565b91507f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008301527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006020830152604082019050919050565b60808201600082015161461a6000850182613fa4565b50602082015161462d60208501826140dc565b5060408201516146406040850182613f95565b50606082015161465360608501826140dc565b50505050565b600060808301600083015184820360008601526146768282613fc2565b915050602083015184820360208601526146908282614020565b915050604083015184820360408601526146aa8282614118565b91505060608301516146bf60608601826140dc565b508091505092915050565b600060c0830160008301516146e260008601826140fa565b5060208301516146f560208601826141a0565b5060408301516147086040860182614182565b50606083015161471b6060860182614182565b50608083015161472e6080860182614753565b5060a083015184820360a08601526147468282614118565b9150508091505092915050565b61475c81614e07565b82525050565b61476b81614e07565b82525050565b61477a81614e11565b82525050565b600061478c8284614151565b915081905092915050565b60006020820190506147ac6000830184613fb3565b92915050565b60006040820190506147c76000830185613fb3565b6147d46020830184613fb3565b9392505050565b60006040820190506147f06000830185613fb3565b6147fd6020830184614762565b9392505050565b600060208201905061481960008301846140eb565b92915050565b60006020820190506148346000830184614109565b92915050565b600060808201905061484f6000830187614109565b61485c6020830186613fb3565b6148696040830185613fb3565b818103606083015261487b8184614659565b905095945050505050565b600060608201905061489b6000830186614191565b81810360208301526148ad818561407e565b90506148bc6040830184614762565b949350505050565b60006020820190506148d960008301846141af565b92915050565b600060208201905081810360008301526148f981846141cd565b905092915050565b6000602082019050818103600083015261491a81614206565b9050919050565b6000602082019050818103600083015261493a81614246565b9050919050565b6000602082019050818103600083015261495a816142ac565b9050919050565b6000602082019050818103600083015261497a816142ec565b9050919050565b6000602082019050818103600083015261499a81614352565b9050919050565b600060208201905081810360008301526149ba816143b8565b9050919050565b600060208201905081810360008301526149da816143f8565b9050919050565b600060208201905081810360008301526149fa81614438565b9050919050565b60006020820190508181036000830152614a1a81614478565b9050919050565b60006020820190508181036000830152614a3a816144b8565b9050919050565b60006020820190508181036000830152614a5a816144f8565b9050919050565b60006020820190508181036000830152614a7a81614538565b9050919050565b60006020820190508181036000830152614a9a8161459e565b9050919050565b600060e0820190508181036000830152614abb81876146ca565b9050614aca6020830186614604565b614ad760a08301856141be565b614ae460c0830184614762565b95945050505050565b6000602082019050614b026000830184614762565b92915050565b6000604082019050614b1d6000830185614762565b614b2a6020830184613fb3565b9392505050565b6000604082019050614b466000830185614762565b614b536020830184614762565b9392505050565b6000606082019050614b6f6000830186614762565b614b7c6020830185614762565b614b896040830184613fb3565b949350505050565b6000602082019050614ba66000830184614771565b92915050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000614c7d82614e07565b9150614c8883614e07565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614cbd57614cbc614ee7565b5b828201905092915050565b6000614cd382614e07565b9150614cde83614e07565b925082614cee57614ced614f16565b5b828204905092915050565b6000614d0482614e07565b9150614d0f83614e07565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614d4857614d47614ee7565b5b828202905092915050565b6000614d5e82614e07565b9150614d6983614e07565b925082821015614d7c57614d7b614ee7565b5b828203905092915050565b6000614d9282614de7565b9050919050565b6000614da482614de7565b9050919050565b60008115159050919050565b6000819050919050565b6000819050614dcf82614f85565b919050565b6000819050614de282614f99565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000614e2982614e30565b9050919050565b6000614e3b82614de7565b9050919050565b6000614e4d82614dc1565b9050919050565b6000614e5f82614dd4565b9050919050565b6000614e7182614e11565b9050919050565b6000614e8382614e07565b9050919050565b60005b83811015614ea8578082015181840152602081019050614e8d565b83811115614eb7576000848401525b50505050565b6000614ec882614e11565b915060ff821415614edc57614edb614ee7565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000601f19601f8301169050919050565b60048110614f9657614f95614f45565b5b50565b60028110614faa57614fa9614f45565b5b50565b614fb681614d87565b8114614fc157600080fd5b50565b614fcd81614dab565b8114614fd857600080fd5b50565b614fe481614db7565b8114614fef57600080fd5b50565b614ffb81614e07565b811461500657600080fd5b50565b61501281614e11565b811461501d57600080fd5b5056fea2646970667358221220b6901c93fc119e7f959b48537cdc3a9498fe44b169bb1b77c90a81ba0ede657064736f6c63430008000033000000000000000000000000fcef8a994209d6916eb2c86cdd2afd60aa6f54b10000000000000000000000000000000000000000000000000000000000000016000000000000000000000000fb8dacdb058e84131d9c4a4bcd18a4f5704b48560000000000000000000000000e7c5313e9bb80b654734d9b7ab1fb01468dee3b

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

000000000000000000000000fcef8a994209d6916eb2c86cdd2afd60aa6f54b10000000000000000000000000000000000000000000000000000000000000016000000000000000000000000fb8dacdb058e84131d9c4a4bcd18a4f5704b48560000000000000000000000000e7c5313e9bb80b654734d9b7ab1fb01468dee3b

-----Decoded View---------------
Arg [0] : _lpToken (address): 0xfcef8a994209d6916eb2c86cdd2afd60aa6f54b1
Arg [1] : _poolId (uint256): 22
Arg [2] : _vault (address): 0xfb8dacdb058e84131d9c4a4bcd18a4f5704b4856
Arg [3] : _treasury (address): 0x0e7c5313e9bb80b654734d9b7ab1fb01468dee3b

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000fcef8a994209d6916eb2c86cdd2afd60aa6f54b1
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [2] : 000000000000000000000000fb8dacdb058e84131d9c4a4bcd18a4f5704b4856
Arg [3] : 0000000000000000000000000e7c5313e9bb80b654734d9b7ab1fb01468dee3b


Deployed ByteCode Sourcemap

87339:16266:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88218:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98861:175;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90638:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88984:105;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89174:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93447:602;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88737:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88835:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99999:119;;;:::i;:::-;;94437:428;;;:::i;:::-;;99661:135;;;:::i;:::-;;90712:45;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88651:79;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38812:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88312:22;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103457:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89393:23;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88954;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88017:84;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2538:103;;;:::i;:::-;;98414:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87920:90;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101938:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99853:87;;;:::i;:::-;;88386:40;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1887:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90533:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91125:37;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89135:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88343:34;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90671;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88762:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98621:123;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101838:92;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90566:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88871:35;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92984:253;;;:::i;:::-;;101000:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90603:28;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88433:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103162:287;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2796:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87831:82;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88798:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88108:89;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101337:228;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101573:134;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99233:308;;;:::i;:::-;;89423:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89096:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88913:34;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88218:87;88262:42;88218:87;:::o;98861:175::-;98907:7;98928:15;98960:10;;;;;;;;;;;98948:32;;;98981:6;;98997:4;98948:55;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98927:76;;;99021:7;99014:14;;;98861:175;:::o;90638:26::-;;;;:::o;88984:105::-;89023:66;88984:105;;;:::o;89174:32::-;;;;:::o;93447:602::-;101770:4;101757:17;;:9;;;;;;;;;;;:17;;;101753:58;;;101790:9;:7;:9::i;:::-;101753:58;93535:5:::1;;;;;;;;;;;93521:19;;:10;:19;;;93513:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;93562:15;93587:7;;;;;;;;;;;93580:25;;;93614:4;93580:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93562:58;;93645:7;93635;:17;93631:194;;;93679:10;;;;;;;;;;;93665:44;;;93710:6;;93718:20;93730:7;93718;:11;;:20;;;;:::i;:::-;93748:4;93665:89;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;93782:7;;;;;;;;;;;93775:25;;;93809:4;93775:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93765:50;;93631:194;93849:7;93839;:17;93835:61;;;93879:7;93869:17;;93835:61;93904:19;93926:45;90752:5;93926:24;93938:11;;93926:7;:11;;:24;;;;:::i;:::-;:28;;:45;;;;:::i;:::-;93904:67;;93980:61;94009:5;;;;;;;;;;;94016:24;94028:11;94016:7;:11;;:24;;;;:::i;:::-;93987:7;;;;;;;;;;;93980:28;;;;:61;;;;;:::i;:::-;101821:1;;93447:602:::0;:::o;88737:18::-;;;;:::o;88835:29::-;;;;;;;;;;;;;:::o;99999:119::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100048:10:::1;:8;:10::i;:::-;100071:17;:15;:17::i;:::-;100101:9;:7;:9::i;:::-;99999:119::o:0;94437:428::-;39138:8;:6;:8::i;:::-;39137:9;39129:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;94497:30:::1;94516:10;94497:18;:30::i;:::-;94496:31;94488:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;94566:10;;;;;;;;;;;94552:33;;;94586:6;;94602:4;94552:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;94619:13;:11;:13::i;:::-;94648:12;;;;;;;;;;;94645:73;;;94662:54;94679:17;;;;;;;;;;;94698;;94662:16;:54::i;:::-;94645:73;94730:41;88154:42;94757:13;;;;;;;;;;;94730;:41::i;:::-;94784:9;:7;:9::i;:::-;94806;:7;:9::i;:::-;94846:10;94833:24;;;;;;;;;;;;94437:428::o:0;99661:135::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99706:7:::1;:5;:7::i;:::-;99736:10;;;;;;;;;;;99724:41;;;99766:6;;99782:4;99724:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;99661:135::o:0;90712:45::-;90752:5;90712:45;:::o;88651:79::-;;;;;;;;;;;;;:::o;38812:86::-;38859:4;38883:7;;;;;;;;;;;38876:14;;38812:86;:::o;88312:22::-;;;;;;;;;;;;;:::o;103457:143::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;103544:2:::1;103536:4;:10;;103528:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;103588:4;103574:11;:18;;;;103457:143:::0;:::o;89393:23::-;;;;;;;;;;;;;:::o;88954:::-;;;;:::o;88017:84::-;88058:42;88017:84;:::o;2538:103::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2603:30:::1;2630:1;2603:18;:30::i;:::-;2538:103::o:0;98414:115::-;98456:7;98483:38;98505:15;:13;:15::i;:::-;98483:17;:15;:17::i;:::-;:21;;:38;;;;:::i;:::-;98476:45;;98414:115;:::o;87920:90::-;87967:42;87920:90;:::o;101938:138::-;102011:4;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102037:11:::1;102026:8;;:22;;;;;;;;;;;;;;;;;;102064:4;102057:11;;101938:138:::0;;;:::o;99853:87::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99896:8:::1;:6;:8::i;:::-;99913:19;:17;:19::i;:::-;99853:87::o:0;88386:40::-;;;;;;;;;;;;;;;;;;;;;;:::o;1887:87::-;1933:7;1960:6;;;;;;;;;;;1953:13;;1887:87;:::o;90533:26::-;;;;:::o;91125:37::-;;;;;;;;;;;;;;;;;;;;;;:::o;89135:32::-;;;;;;;;;;;;;:::o;88343:34::-;;;;;;;;;;;;;:::o;90671:::-;90702:3;90671:34;:::o;88762:27::-;;;;:::o;98621:123::-;98669:7;98703;;;;;;;;;;;98696:25;;;98730:4;98696:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98689:47;;98621:123;:::o;101838:92::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101917:5:::1;101906:8;:16;;;;101838:92:::0;:::o;90566:30::-;;;;:::o;88871:35::-;;;;;;;;;;;;;:::o;92984:253::-;39138:8;:6;:8::i;:::-;39137:9;39129:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;101770:4:::1;101757:17;;:9;;;;;;;;;;;:17;;;101753:58;;;101790:9;:7;:9::i;:::-;101753:58;93050:15:::2;93075:7;;;;;;;;;;;93068:25;;;93102:4;93068:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93050:58;;93135:1;93125:7;:11;93121:109;;;93167:10;;;;;;;;;;;93153:33;;;93187:6;;93195:7;93212:4;93153:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;93121:109;101821:1;92984:253::o:0;101000:224::-;101068:4;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;90702:3:::1;101091:9;:20;;101083:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;101148:9;101137:8;:20;;;;101171:25;101187:8;;101171:25;;;;;;:::i;:::-;;;;;;;;101212:4;101205:11;;101000:224:::0;;;:::o;90603:28::-;;;;:::o;88433:29::-;;;;;;;;;;;;;:::o;103162:287::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;88154:42:::1;103276:20;;:5;:20;;;;103268:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;103363:6;103348:12;;:21;;;;;;;;;;;;;;;;;;103400:5;103380:17;;:25;;;;;;;;;;;;;;;;;;103436:5;103416:17;:25;;;;103162:287:::0;;;:::o;2796:201::-;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2905:1:::1;2885:22;;:8;:22;;;;2877:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2961:28;2980:8;2961:18;:28::i;:::-;2796:201:::0;:::o;87831:82::-;87870:42;87831:82;:::o;88798:30::-;;;;;;;;;;;;;:::o;88108:89::-;88154:42;88108:89;:::o;101337:228::-;101403:4;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101428:8:::1;101418:7;:18;;;;101459:28;101479:7;;90752:5;101459:19;;:28;;;;:::i;:::-;101445:11;:42;;;;101501:36;101516:7;;101525:11;;101501:36;;;;;;;:::i;:::-;;;;;;;;101553:4;101546:11;;101337:228:::0;;;:::o;101573:134::-;101641:4;2118:12;:10;:12::i;:::-;2107:23;;:7;:5;:7::i;:::-;:23;;;2099:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101669:8:::1;101657:9;;:20;;;;;;;;;;;;;;;;;;101695:4;101688:11;;101573:134:::0;;;:::o;99233:308::-;99298:5;;;;;;;;;;;99284:19;;:10;:19;;;99276:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;99341:10;;;;;;;;;;;99327:44;;;99372:6;;99380:15;:13;:15::i;:::-;99405:4;99327:84;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99424:15;99449:7;;;;;;;;;;;99442:25;;;99476:4;99442:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99424:58;;99500:7;;;;;;;;;;;99493:24;;;99518:5;;;;;;;;;;;99525:7;99493:40;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;99233:308;:::o;89423:20::-;;;;;;;;;;;;;:::o;89096:32::-;;;;;;;;;;;;;:::o;88913:34::-;;;;;;;;;;;;;:::o;35179:616::-;35552:1;35543:5;:10;35542:62;;;;35602:1;35559:5;:15;;;35583:4;35590:7;35559:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;35542:62;35520:166;;;;;;;;;;;;:::i;:::-;;;;;;;;;35697:90;35717:5;35747:22;;;35771:7;35780:5;35724:62;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35697:19;:90::i;:::-;35179:616;;;:::o;16711:229::-;16848:12;16880:52;16902:6;16910:4;16916:1;16919:12;16880:21;:52::i;:::-;16873:59;;16711:229;;;;;:::o;9357:98::-;9415:7;9446:1;9442;:5;;;;:::i;:::-;9435:12;;9357:98;;;;:::o;9714:::-;9772:7;9803:1;9799;:5;;;;:::i;:::-;9792:12;;9714:98;;;;:::o;10113:::-;10171:7;10202:1;10198;:5;;;;:::i;:::-;10191:12;;10113:98;;;;:::o;34443:211::-;34560:86;34580:5;34610:23;;;34635:2;34639:5;34587:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34560:19;:86::i;:::-;34443:211;;;:::o;670:98::-;723:7;750:10;743:17;;670:98;:::o;39871:120::-;39415:8;:6;:8::i;:::-;39407:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;39940:5:::1;39930:7:::0;::::1;:15;;;;;;;;;;;;;;;;;;39961:22;39970:12;:10;:12::i;:::-;39961:22;;;;;;:::i;:::-;;;;;;;;39871:120::o:0;100126:532::-;100173:43;88058:42;100214:1;87967:42;100173:32;;;;:43;;;;;:::i;:::-;100227:45;88262:42;100270:1;88154:42;100227:31;;;;:45;;;;;:::i;:::-;100283:38;88262:42;100319:1;87870:42;100283:24;;;;:38;;;;;:::i;:::-;100332:41;100359:10;;;;;;;;;;;100371:1;88058:42;100332:26;;;;:41;;;;;:::i;:::-;100384:59;88058:42;100425:17;87967:42;100384:32;;;;:59;;;;;:::i;:::-;100454:61;88262:42;100497:17;88154:42;100454:31;;;;:61;;;;;:::i;:::-;100526:54;88262:42;100562:17;87870:42;100526:24;;;;:54;;;;;:::i;:::-;100591:57;100618:10;;;;;;;;;;;100630:17;88058:42;100591:26;;;;:57;;;;;:::i;:::-;100126:532::o;13905:387::-;13965:4;14173:12;14240:7;14228:20;14220:28;;14283:1;14276:4;:8;14269:15;;;13905:387;;;:::o;95203:736::-;95246:17;88154:42;95266:29;;;95304:4;95266:44;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95246:64;;95321:15;87870:42;95339:22;;;95370:4;95339:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95321:55;;95389:12;95412:16;95460:44;90752:5;95460:23;95474:8;;95460:9;:13;;:23;;;;:::i;:::-;:27;;:44;;;;:::i;:::-;95453:51;;95515:44;88154:42;87870;89023:66;95540:12;;95554:4;95515:5;:44::i;:::-;95581:50;95623:7;87870:42;95581:22;;;95612:4;95581:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;:50;;;;:::i;:::-;95570:61;;95644:21;95668:42;90752:5;95668:21;95681:7;;95668:8;:12;;:21;;;;:::i;:::-;:25;;:42;;;;:::i;:::-;95644:66;;95721:52;95747:10;95759:13;87870:42;95721:25;;;;:52;;;;;:::i;:::-;95788:26;95817:46;90752:5;95817:25;95830:11;;95817:8;:12;;:25;;;;:::i;:::-;:29;;:46;;;;:::i;:::-;95788:75;;95874:55;95900:8;;;;;;;;;;;95910:18;87870:42;95874:25;;;;:55;;;;;:::i;:::-;95203:736;;;;;;:::o;102084:834::-;102166:15;87870:42;102184:22;;;102215:4;102184:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102166:55;;102236:11;102257:5;102250:23;;;102282:4;102250:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102236:52;;102303:30;102309:5;87870:42;102322:5;102329:3;102303:5;:30::i;:::-;102348:12;102363:85;90752:5;102363:64;102418:8;;102363:50;102405:7;87870:42;102363:22;;;102394:4;102363:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;:50;;;;:::i;:::-;:54;;:64;;;;:::i;:::-;:68;;:85;;;;:::i;:::-;102348:100;;102465:21;102489:38;90752:5;102489:17;102498:7;;102489:4;:8;;:17;;;;:::i;:::-;:21;;:38;;;;:::i;:::-;102465:62;;102542:52;102568:10;102580:13;87870:42;102542:25;;;;:52;;;;;:::i;:::-;102611:26;102640:42;90752:5;102640:21;102649:11;;102640:4;:8;;:21;;;;:::i;:::-;:25;;:42;;;;:::i;:::-;102611:71;;102697:55;102723:8;;;;;;;;;;;102733:18;87870:42;102697:25;;;;:55;;;;;:::i;:::-;87870:42;102793:22;;;102824:4;102793:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102783:47;;102845;87870:42;88154;89023:66;102870:12;;102884:7;102845:5;:47::i;:::-;102084:834;;;;;;;:::o;97031:1175::-;97105:27;97142:5;97135:23;;;97167:4;97135:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97105:68;;97186:39;88262:42;97223:1;97193:5;97186:25;;;;:39;;;;;:::i;:::-;97236:57;88262:42;97273:19;97243:5;97236:25;;;;:57;;;;;:::i;:::-;97306:35;97344:54;97306:92;;97409:26;97452:21;;;;;;;;;;;97438:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97409:65;;97507:19;97485:9;97495:8;97485:19;;;;;;;;;;;;;;;;;;;;;;;:41;;;;;97537:20;97560:1;97537:24;;97572:23;97611:21;;;;;;;;;;;97598:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97572:61;;97648:7;97644:102;97665:21;;;;;;;;;;;97661:25;;:1;:25;;;97644:102;;;97727:3;:6;97731:1;97727:6;;;;;;;;;;;;;;;;;;;;;;;;;97707:7;97715:1;97707:10;;;;;;;;;;;;;;;;;;;;;;;:27;;;;;;;;;;;97688:3;;;;;:::i;:::-;;;;97644:102;;;;97762:21;97797:8;97807:9;97818:12;97786:45;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;97762:69;;97844:37;;:::i;:::-;97909:7;97892;:14;;:24;;;;97950:9;97927:7;:20;;:32;;;;97989:8;97970:7;:16;;:27;;;;98038:5;98008:7;:27;;:35;;;;;;;;;;;88262:42;98056:26;;;98097:12;;98132:4;98160;98180:7;98056:142;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97031:1175;;;;;;;;;:::o;94873:149::-;94912:13;87967:42;94928:30;;;94967:4;94928:45;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94912:61;;88058:42;94984:23;;;95008:5;94984:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94873:149;:::o;3157:191::-;3231:16;3250:6;;;;;;;;;;;3231:25;;3276:8;3267:6;;:17;;;;;;;;;;;;;;;;;;3331:8;3300:40;;3321:8;3300:40;;;;;;;;;;;;3157:191;;:::o;8976:98::-;9034:7;9065:1;9061;:5;;;;:::i;:::-;9054:12;;8976:98;;;;:::o;39612:118::-;39138:8;:6;:8::i;:::-;39137:9;39129:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;39682:4:::1;39672:7;;:14;;;;;;;;;;;;;;;;;;39702:20;39709:12;:10;:12::i;:::-;39702:20;;;;;;:::i;:::-;;;;;;;;39612:118::o:0;100666:257::-;100715:43;88058:42;100756:1;87967:42;100715:32;;;;:43;;;;;:::i;:::-;100769:45;88262:42;100812:1;88154:42;100769:31;;;;:45;;;;;:::i;:::-;100825:38;88262:42;100861:1;87870:42;100825:24;;;;:38;;;;;:::i;:::-;100874:41;100901:10;;;;;;;;;;;100913:1;88058:42;100874:26;;;;:41;;;;;:::i;:::-;100666:257::o;37016:716::-;37440:23;37466:69;37494:4;37466:69;;;;;;;;;;;;;;;;;37474:5;37466:27;;;;:69;;;;;:::i;:::-;37440:95;;37570:1;37550:10;:17;:21;37546:179;;;37647:10;37636:30;;;;;;;;;;;;:::i;:::-;37628:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;37546:179;37016:716;;;:::o;17831:510::-;18001:12;18059:5;18034:21;:30;;18026:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;18126:18;18137:6;18126:10;:18::i;:::-;18118:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;18192:12;18206:23;18233:6;:11;;18252:5;18259:4;18233:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18191:73;;;;18282:51;18299:7;18308:10;18320:12;18282:16;:51::i;:::-;18275:58;;;;17831:510;;;;;;:::o;96033:885::-;96137:35;;:::i;:::-;96183:24;96267:5;96247:10;:17;;:25;;;;;96301:8;96283:10;:15;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96348:8;96320:10;:18;;:37;;;;;;;;;;;96397:9;96368:10;:19;;:39;;;;;;;;;;;96438:6;96418:10;:17;;:26;;;;;96488:1;96477:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;96455:10;:19;;:35;;;;96503:34;;:::i;:::-;96571:4;96548:5;:12;;:28;;;;;;;;;;;96615:5;96587;:25;;:33;;;;;;;;;;;96665:4;96631:5;:15;;:40;;;;;;;;;;;96708:5;96682;:23;;:31;;;;;;;;;;;96726:42;88262;96766:1;96733:8;96726:28;;;;:42;;;;;:::i;:::-;96779:47;88262:42;96819:6;96786:8;96779:28;;;;:47;;;;;:::i;:::-;88262:42;96839:22;;;96862:10;96874:5;96881:1;96903:3;96885:15;:21;;;;:::i;:::-;96839:69;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;96033:885;;;;;;;:::o;20517:712::-;20667:12;20696:7;20692:530;;;20727:10;20720:17;;;;20692:530;20861:1;20841:10;:17;:21;20837:374;;;21039:10;21033:17;21100:15;21087:10;21083:2;21079:19;21072:44;20987:148;21182:12;21175:20;;;;;;;;;;;:::i;:::-;;;;;;;;20517:712;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:139:1:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:133::-;;233:6;220:20;211:29;;249:30;273:5;249:30;:::i;:::-;201:84;;;;:::o;291:137::-;;376:6;370:13;361:22;;392:30;416:5;392:30;:::i;:::-;351:77;;;;:::o;434:139::-;;518:6;505:20;496:29;;534:33;561:5;534:33;:::i;:::-;486:87;;;;:::o;579:139::-;;663:6;650:20;641:29;;679:33;706:5;679:33;:::i;:::-;631:87;;;;:::o;724:143::-;;812:6;806:13;797:22;;828:33;855:5;828:33;:::i;:::-;787:80;;;;:::o;873:135::-;;955:6;942:20;933:29;;971:31;996:5;971:31;:::i;:::-;923:85;;;;:::o;1014:262::-;;1122:2;1110:9;1101:7;1097:23;1093:32;1090:2;;;1138:1;1135;1128:12;1090:2;1181:1;1206:53;1251:7;1242:6;1231:9;1227:22;1206:53;:::i;:::-;1196:63;;1152:117;1080:196;;;;:::o;1282:256::-;;1387:2;1375:9;1366:7;1362:23;1358:32;1355:2;;;1403:1;1400;1393:12;1355:2;1446:1;1471:50;1513:7;1504:6;1493:9;1489:22;1471:50;:::i;:::-;1461:60;;1417:114;1345:193;;;;:::o;1544:278::-;;1660:2;1648:9;1639:7;1635:23;1631:32;1628:2;;;1676:1;1673;1666:12;1628:2;1719:1;1744:61;1797:7;1788:6;1777:9;1773:22;1744:61;:::i;:::-;1734:71;;1690:125;1618:204;;;;:::o;1828:546::-;;;;1967:2;1955:9;1946:7;1942:23;1938:32;1935:2;;;1983:1;1980;1973:12;1935:2;2026:1;2051:50;2093:7;2084:6;2073:9;2069:22;2051:50;:::i;:::-;2041:60;;1997:114;2150:2;2176:53;2221:7;2212:6;2201:9;2197:22;2176:53;:::i;:::-;2166:63;;2121:118;2278:2;2304:53;2349:7;2340:6;2329:9;2325:22;2304:53;:::i;:::-;2294:63;;2249:118;1925:449;;;;;:::o;2380:262::-;;2488:2;2476:9;2467:7;2463:23;2459:32;2456:2;;;2504:1;2501;2494:12;2456:2;2547:1;2572:53;2617:7;2608:6;2597:9;2593:22;2572:53;:::i;:::-;2562:63;;2518:117;2446:196;;;;:::o;2648:262::-;;2756:2;2744:9;2735:7;2731:23;2727:32;2724:2;;;2772:1;2769;2762:12;2724:2;2815:1;2840:53;2885:7;2876:6;2865:9;2861:22;2840:53;:::i;:::-;2830:63;;2786:117;2714:196;;;;:::o;2916:284::-;;3035:2;3023:9;3014:7;3010:23;3006:32;3003:2;;;3051:1;3048;3041:12;3003:2;3094:1;3119:64;3175:7;3166:6;3155:9;3151:22;3119:64;:::i;:::-;3109:74;;3065:128;2993:207;;;;:::o;3206:440::-;;;3342:2;3330:9;3321:7;3317:23;3313:32;3310:2;;;3358:1;3355;3348:12;3310:2;3401:1;3426:64;3482:7;3473:6;3462:9;3458:22;3426:64;:::i;:::-;3416:74;;3372:128;3539:2;3565:64;3621:7;3612:6;3601:9;3597:22;3565:64;:::i;:::-;3555:74;;3510:129;3300:346;;;;;:::o;3652:258::-;;3758:2;3746:9;3737:7;3733:23;3729:32;3726:2;;;3774:1;3771;3764:12;3726:2;3817:1;3842:51;3885:7;3876:6;3865:9;3861:22;3842:51;:::i;:::-;3832:61;;3788:115;3716:194;;;;:::o;3916:209::-;;4021:61;4078:3;4070:6;4021:61;:::i;:::-;4114:4;4109:3;4105:14;4091:28;;4011:114;;;;:::o;4131:179::-;;4221:46;4263:3;4255:6;4221:46;:::i;:::-;4299:4;4294:3;4290:14;4276:28;;4211:99;;;;:::o;4316:132::-;4409:32;4435:5;4409:32;:::i;:::-;4404:3;4397:45;4387:61;;:::o;4454:108::-;4531:24;4549:5;4531:24;:::i;:::-;4526:3;4519:37;4509:53;;:::o;4568:118::-;4655:24;4673:5;4655:24;:::i;:::-;4650:3;4643:37;4633:53;;:::o;4730:787::-;;4883:69;4946:5;4883:69;:::i;:::-;4968:76;5037:6;5032:3;4968:76;:::i;:::-;4961:83;;5068:71;5133:5;5068:71;:::i;:::-;5162:7;5193:1;5178:314;5203:6;5200:1;5197:13;5178:314;;;5279:6;5273:13;5306:78;5380:3;5365:13;5306:78;:::i;:::-;5299:85;;5407:75;5475:6;5407:75;:::i;:::-;5397:85;;5238:254;5225:1;5222;5218:9;5213:14;;5178:314;;;5182:14;5508:3;5501:10;;4859:658;;;;;;;:::o;5553:712::-;;5691:54;5739:5;5691:54;:::i;:::-;5761:76;5830:6;5825:3;5761:76;:::i;:::-;5754:83;;5861:56;5911:5;5861:56;:::i;:::-;5940:7;5971:1;5956:284;5981:6;5978:1;5975:13;5956:284;;;6057:6;6051:13;6084:63;6143:3;6128:13;6084:63;:::i;:::-;6077:70;;6170:60;6223:6;6170:60;:::i;:::-;6160:70;;6016:224;6003:1;6000;5996:9;5991:14;;5956:284;;;5960:14;6256:3;6249:10;;5667:598;;;;;;;:::o;6301:732::-;;6449:54;6497:5;6449:54;:::i;:::-;6519:86;6598:6;6593:3;6519:86;:::i;:::-;6512:93;;6629:56;6679:5;6629:56;:::i;:::-;6708:7;6739:1;6724:284;6749:6;6746:1;6743:13;6724:284;;;6825:6;6819:13;6852:63;6911:3;6896:13;6852:63;:::i;:::-;6845:70;;6938:60;6991:6;6938:60;:::i;:::-;6928:70;;6784:224;6771:1;6768;6764:9;6759:14;;6724:284;;;6728:14;7024:3;7017:10;;6425:608;;;;;;;:::o;7039:99::-;7110:21;7125:5;7110:21;:::i;:::-;7105:3;7098:34;7088:50;;:::o;7144:109::-;7225:21;7240:5;7225:21;:::i;:::-;7220:3;7213:34;7203:50;;:::o;7259:108::-;7336:24;7354:5;7336:24;:::i;:::-;7331:3;7324:37;7314:53;;:::o;7373:118::-;7460:24;7478:5;7460:24;:::i;:::-;7455:3;7448:37;7438:53;;:::o;7497:340::-;;7601:38;7633:5;7601:38;:::i;:::-;7655:60;7708:6;7703:3;7655:60;:::i;:::-;7648:67;;7724:52;7769:6;7764:3;7757:4;7750:5;7746:16;7724:52;:::i;:::-;7801:29;7823:6;7801:29;:::i;:::-;7796:3;7792:39;7785:46;;7577:260;;;;;:::o;7843:373::-;;7975:38;8007:5;7975:38;:::i;:::-;8029:88;8110:6;8105:3;8029:88;:::i;:::-;8022:95;;8126:52;8171:6;8166:3;8159:4;8152:5;8148:16;8126:52;:::i;:::-;8203:6;8198:3;8194:16;8187:23;;7951:265;;;;;:::o;8222:151::-;8314:52;8360:5;8314:52;:::i;:::-;8309:3;8302:65;8292:81;;:::o;8379:153::-;8477:48;8519:5;8477:48;:::i;:::-;8472:3;8465:61;8455:77;;:::o;8538:143::-;8626:48;8668:5;8626:48;:::i;:::-;8621:3;8614:61;8604:77;;:::o;8687:143::-;8780:43;8817:5;8780:43;:::i;:::-;8775:3;8768:56;8758:72;;:::o;8836:147::-;8931:45;8970:5;8931:45;:::i;:::-;8926:3;8919:58;8909:74;;:::o;8989:364::-;;9105:39;9138:5;9105:39;:::i;:::-;9160:71;9224:6;9219:3;9160:71;:::i;:::-;9153:78;;9240:52;9285:6;9280:3;9273:4;9266:5;9262:16;9240:52;:::i;:::-;9317:29;9339:6;9317:29;:::i;:::-;9312:3;9308:39;9301:46;;9081:272;;;;;:::o;9359:318::-;;9522:67;9586:2;9581:3;9522:67;:::i;:::-;9515:74;;9619:22;9615:1;9610:3;9606:11;9599:43;9668:2;9663:3;9659:12;9652:19;;9505:172;;;:::o;9683:370::-;;9846:67;9910:2;9905:3;9846:67;:::i;:::-;9839:74;;9943:34;9939:1;9934:3;9930:11;9923:55;10009:8;10004:2;9999:3;9995:12;9988:30;10044:2;10039:3;10035:12;10028:19;;9829:224;;;:::o;10059:306::-;;10222:66;10286:1;10281:3;10222:66;:::i;:::-;10215:73;;10318:11;10314:1;10309:3;10305:11;10298:32;10356:2;10351:3;10347:12;10340:19;;10205:160;;;:::o;10371:368::-;;10534:67;10598:2;10593:3;10534:67;:::i;:::-;10527:74;;10631:34;10627:1;10622:3;10618:11;10611:55;10697:6;10692:2;10687:3;10683:12;10676:28;10730:2;10725:3;10721:12;10714:19;;10517:222;;;:::o;10745:370::-;;10908:67;10972:2;10967:3;10908:67;:::i;:::-;10901:74;;11005:34;11001:1;10996:3;10992:11;10985:55;11071:8;11066:2;11061:3;11057:12;11050:30;11106:2;11101:3;11097:12;11090:19;;10891:224;;;:::o;11121:314::-;;11284:67;11348:2;11343:3;11284:67;:::i;:::-;11277:74;;11381:18;11377:1;11372:3;11368:11;11361:39;11426:2;11421:3;11417:12;11410:19;;11267:168;;;:::o;11441:303::-;;11604:66;11668:1;11663:3;11604:66;:::i;:::-;11597:73;;11700:8;11696:1;11691:3;11687:11;11680:29;11735:2;11730:3;11726:12;11719:19;;11587:157;;;:::o;11750:330::-;;11913:67;11977:2;11972:3;11913:67;:::i;:::-;11906:74;;12010:34;12006:1;12001:3;11997:11;11990:55;12071:2;12066:3;12062:12;12055:19;;11896:184;;;:::o;12086:310::-;;12249:67;12313:2;12308:3;12249:67;:::i;:::-;12242:74;;12346:14;12342:1;12337:3;12333:11;12326:35;12387:2;12382:3;12378:12;12371:19;;12232:164;;;:::o;12402:327::-;;12565:67;12629:2;12624:3;12565:67;:::i;:::-;12558:74;;12662:31;12658:1;12653:3;12649:11;12642:52;12720:2;12715:3;12711:12;12704:19;;12548:181;;;:::o;12735:310::-;;12898:67;12962:2;12957:3;12898:67;:::i;:::-;12891:74;;12995:14;12991:1;12986:3;12982:11;12975:35;13036:2;13031:3;13027:12;13020:19;;12881:164;;;:::o;13051:374::-;;13214:67;13278:2;13273:3;13214:67;:::i;:::-;13207:74;;13311:34;13307:1;13302:3;13298:11;13291:55;13377:12;13372:2;13367:3;13363:12;13356:34;13416:2;13411:3;13407:12;13400:19;;13197:228;;;:::o;13431:386::-;;13594:67;13658:2;13653:3;13594:67;:::i;:::-;13587:74;;13691:34;13687:1;13682:3;13678:11;13671:55;13757:24;13752:2;13747:3;13743:12;13736:46;13808:2;13803:3;13799:12;13792:19;;13577:240;;;:::o;13891:908::-;14052:4;14047:3;14043:14;14141:4;14134:5;14130:16;14124:23;14160:63;14217:4;14212:3;14208:14;14194:12;14160:63;:::i;:::-;14067:166;14330:4;14323:5;14319:16;14313:23;14349:57;14400:4;14395:3;14391:14;14377:12;14349:57;:::i;:::-;14243:173;14503:4;14496:5;14492:16;14486:23;14522:79;14595:4;14590:3;14586:14;14572:12;14522:79;:::i;:::-;14426:185;14706:4;14699:5;14695:16;14689:23;14725:57;14776:4;14771:3;14767:14;14753:12;14725:57;:::i;:::-;14621:171;14021:778;;;:::o;14875:1208::-;;15046:4;15041:3;15037:14;15135:4;15128:5;15124:16;15118:23;15188:3;15182:4;15178:14;15171:4;15166:3;15162:14;15155:38;15214:118;15327:4;15313:12;15214:118;:::i;:::-;15206:126;;15061:282;15433:4;15426:5;15422:16;15416:23;15486:3;15480:4;15476:14;15469:4;15464:3;15460:14;15453:38;15512:103;15610:4;15596:12;15512:103;:::i;:::-;15504:111;;15353:273;15712:4;15705:5;15701:16;15695:23;15765:3;15759:4;15755:14;15748:4;15743:3;15739:14;15732:38;15791:71;15857:4;15843:12;15791:71;:::i;:::-;15783:79;;15636:237;15970:4;15963:5;15959:16;15953:23;15989:57;16040:4;16035:3;16031:14;16017:12;15989:57;:::i;:::-;15883:173;16073:4;16066:11;;15015:1068;;;;;:::o;16149:1362::-;;16310:4;16305:3;16301:14;16399:4;16392:5;16388:16;16382:23;16418:63;16475:4;16470:3;16466:14;16452:12;16418:63;:::i;:::-;16325:166;16573:4;16566:5;16562:16;16556:23;16592:74;16660:4;16655:3;16651:14;16637:12;16592:74;:::i;:::-;16501:175;16761:4;16754:5;16750:16;16744:23;16780:78;16852:4;16847:3;16843:14;16829:12;16780:78;:::i;:::-;16686:182;16954:4;16947:5;16943:16;16937:23;16973:78;17045:4;17040:3;17036:14;17022:12;16973:78;:::i;:::-;16878:183;17145:4;17138:5;17134:16;17128:23;17164:63;17221:4;17216:3;17212:14;17198:12;17164:63;:::i;:::-;17071:166;17323:4;17316:5;17312:16;17306:23;17376:3;17370:4;17366:14;17359:4;17354:3;17350:14;17343:38;17402:71;17468:4;17454:12;17402:71;:::i;:::-;17394:79;;17247:237;17501:4;17494:11;;16279:1232;;;;;:::o;17517:108::-;17594:24;17612:5;17594:24;:::i;:::-;17589:3;17582:37;17572:53;;:::o;17631:118::-;17718:24;17736:5;17718:24;:::i;:::-;17713:3;17706:37;17696:53;;:::o;17755:112::-;17838:22;17854:5;17838:22;:::i;:::-;17833:3;17826:35;17816:51;;:::o;17873:271::-;;18025:93;18114:3;18105:6;18025:93;:::i;:::-;18018:100;;18135:3;18128:10;;18007:137;;;;:::o;18150:222::-;;18281:2;18270:9;18266:18;18258:26;;18294:71;18362:1;18351:9;18347:17;18338:6;18294:71;:::i;:::-;18248:124;;;;:::o;18378:332::-;;18537:2;18526:9;18522:18;18514:26;;18550:71;18618:1;18607:9;18603:17;18594:6;18550:71;:::i;:::-;18631:72;18699:2;18688:9;18684:18;18675:6;18631:72;:::i;:::-;18504:206;;;;;:::o;18716:332::-;;18875:2;18864:9;18860:18;18852:26;;18888:71;18956:1;18945:9;18941:17;18932:6;18888:71;:::i;:::-;18969:72;19037:2;19026:9;19022:18;19013:6;18969:72;:::i;:::-;18842:206;;;;;:::o;19054:210::-;;19179:2;19168:9;19164:18;19156:26;;19192:65;19254:1;19243:9;19239:17;19230:6;19192:65;:::i;:::-;19146:118;;;;:::o;19270:222::-;;19401:2;19390:9;19386:18;19378:26;;19414:71;19482:1;19471:9;19467:17;19458:6;19414:71;:::i;:::-;19368:124;;;;:::o;19498:736::-;;19779:3;19768:9;19764:19;19756:27;;19793:71;19861:1;19850:9;19846:17;19837:6;19793:71;:::i;:::-;19874:72;19942:2;19931:9;19927:18;19918:6;19874:72;:::i;:::-;19956;20024:2;20013:9;20009:18;20000:6;19956:72;:::i;:::-;20075:9;20069:4;20065:20;20060:2;20049:9;20045:18;20038:48;20103:124;20222:4;20213:6;20103:124;:::i;:::-;20095:132;;19746:488;;;;;;;:::o;20240:615::-;;20488:2;20477:9;20473:18;20465:26;;20501:82;20580:1;20569:9;20565:17;20556:6;20501:82;:::i;:::-;20630:9;20624:4;20620:20;20615:2;20604:9;20600:18;20593:48;20658:108;20761:4;20752:6;20658:108;:::i;:::-;20650:116;;20776:72;20844:2;20833:9;20829:18;20820:6;20776:72;:::i;:::-;20455:400;;;;;;:::o;20861:234::-;;20998:2;20987:9;20983:18;20975:26;;21011:77;21085:1;21074:9;21070:17;21061:6;21011:77;:::i;:::-;20965:130;;;;:::o;21101:313::-;;21252:2;21241:9;21237:18;21229:26;;21301:9;21295:4;21291:20;21287:1;21276:9;21272:17;21265:47;21329:78;21402:4;21393:6;21329:78;:::i;:::-;21321:86;;21219:195;;;;:::o;21420:419::-;;21624:2;21613:9;21609:18;21601:26;;21673:9;21667:4;21663:20;21659:1;21648:9;21644:17;21637:47;21701:131;21827:4;21701:131;:::i;:::-;21693:139;;21591:248;;;:::o;21845:419::-;;22049:2;22038:9;22034:18;22026:26;;22098:9;22092:4;22088:20;22084:1;22073:9;22069:17;22062:47;22126:131;22252:4;22126:131;:::i;:::-;22118:139;;22016:248;;;:::o;22270:419::-;;22474:2;22463:9;22459:18;22451:26;;22523:9;22517:4;22513:20;22509:1;22498:9;22494:17;22487:47;22551:131;22677:4;22551:131;:::i;:::-;22543:139;;22441:248;;;:::o;22695:419::-;;22899:2;22888:9;22884:18;22876:26;;22948:9;22942:4;22938:20;22934:1;22923:9;22919:17;22912:47;22976:131;23102:4;22976:131;:::i;:::-;22968:139;;22866:248;;;:::o;23120:419::-;;23324:2;23313:9;23309:18;23301:26;;23373:9;23367:4;23363:20;23359:1;23348:9;23344:17;23337:47;23401:131;23527:4;23401:131;:::i;:::-;23393:139;;23291:248;;;:::o;23545:419::-;;23749:2;23738:9;23734:18;23726:26;;23798:9;23792:4;23788:20;23784:1;23773:9;23769:17;23762:47;23826:131;23952:4;23826:131;:::i;:::-;23818:139;;23716:248;;;:::o;23970:419::-;;24174:2;24163:9;24159:18;24151:26;;24223:9;24217:4;24213:20;24209:1;24198:9;24194:17;24187:47;24251:131;24377:4;24251:131;:::i;:::-;24243:139;;24141:248;;;:::o;24395:419::-;;24599:2;24588:9;24584:18;24576:26;;24648:9;24642:4;24638:20;24634:1;24623:9;24619:17;24612:47;24676:131;24802:4;24676:131;:::i;:::-;24668:139;;24566:248;;;:::o;24820:419::-;;25024:2;25013:9;25009:18;25001:26;;25073:9;25067:4;25063:20;25059:1;25048:9;25044:17;25037:47;25101:131;25227:4;25101:131;:::i;:::-;25093:139;;24991:248;;;:::o;25245:419::-;;25449:2;25438:9;25434:18;25426:26;;25498:9;25492:4;25488:20;25484:1;25473:9;25469:17;25462:47;25526:131;25652:4;25526:131;:::i;:::-;25518:139;;25416:248;;;:::o;25670:419::-;;25874:2;25863:9;25859:18;25851:26;;25923:9;25917:4;25913:20;25909:1;25898:9;25894:17;25887:47;25951:131;26077:4;25951:131;:::i;:::-;25943:139;;25841:248;;;:::o;26095:419::-;;26299:2;26288:9;26284:18;26276:26;;26348:9;26342:4;26338:20;26334:1;26323:9;26319:17;26312:47;26376:131;26502:4;26376:131;:::i;:::-;26368:139;;26266:248;;;:::o;26520:419::-;;26724:2;26713:9;26709:18;26701:26;;26773:9;26767:4;26763:20;26759:1;26748:9;26744:17;26737:47;26801:131;26927:4;26801:131;:::i;:::-;26793:139;;26691:248;;;:::o;26945:862::-;;27288:3;27277:9;27273:19;27265:27;;27338:9;27332:4;27328:20;27324:1;27313:9;27309:17;27302:47;27366:114;27475:4;27466:6;27366:114;:::i;:::-;27358:122;;27490:136;27622:2;27611:9;27607:18;27598:6;27490:136;:::i;:::-;27636:81;27712:3;27701:9;27697:19;27688:6;27636:81;:::i;:::-;27727:73;27795:3;27784:9;27780:19;27771:6;27727:73;:::i;:::-;27255:552;;;;;;;:::o;27813:222::-;;27944:2;27933:9;27929:18;27921:26;;27957:71;28025:1;28014:9;28010:17;28001:6;27957:71;:::i;:::-;27911:124;;;;:::o;28041:332::-;;28200:2;28189:9;28185:18;28177:26;;28213:71;28281:1;28270:9;28266:17;28257:6;28213:71;:::i;:::-;28294:72;28362:2;28351:9;28347:18;28338:6;28294:72;:::i;:::-;28167:206;;;;;:::o;28379:332::-;;28538:2;28527:9;28523:18;28515:26;;28551:71;28619:1;28608:9;28604:17;28595:6;28551:71;:::i;:::-;28632:72;28700:2;28689:9;28685:18;28676:6;28632:72;:::i;:::-;28505:206;;;;;:::o;28717:442::-;;28904:2;28893:9;28889:18;28881:26;;28917:71;28985:1;28974:9;28970:17;28961:6;28917:71;:::i;:::-;28998:72;29066:2;29055:9;29051:18;29042:6;28998:72;:::i;:::-;29080;29148:2;29137:9;29133:18;29124:6;29080:72;:::i;:::-;28871:288;;;;;;:::o;29165:214::-;;29292:2;29281:9;29277:18;29269:26;;29305:67;29369:1;29358:9;29354:17;29345:6;29305:67;:::i;:::-;29259:120;;;;:::o;29385:147::-;;29490:3;29482:11;;29520:4;29515:3;29511:14;29503:22;;29472:60;;;:::o;29538:132::-;;29628:3;29620:11;;29658:4;29653:3;29649:14;29641:22;;29610:60;;;:::o;29676:129::-;;29792:5;29786:12;29776:22;;29765:40;;;:::o;29811:114::-;;29912:5;29906:12;29896:22;;29885:40;;;:::o;29931:98::-;;30016:5;30010:12;30000:22;;29989:40;;;:::o;30035:99::-;;30121:5;30115:12;30105:22;;30094:40;;;:::o;30140:128::-;;30257:4;30252:3;30248:14;30240:22;;30230:38;;;:::o;30274:113::-;;30376:4;30371:3;30367:14;30359:22;;30349:38;;;:::o;30393:174::-;;30516:6;30511:3;30504:19;30556:4;30551:3;30547:14;30532:29;;30494:73;;;;:::o;30573:174::-;;30696:6;30691:3;30684:19;30736:4;30731:3;30727:14;30712:29;;30674:73;;;;:::o;30753:184::-;;30886:6;30881:3;30874:19;30926:4;30921:3;30917:14;30902:29;;30864:73;;;;:::o;30943:158::-;;31050:6;31045:3;31038:19;31090:4;31085:3;31081:14;31066:29;;31028:73;;;;:::o;31107:147::-;;31245:3;31230:18;;31220:34;;;;:::o;31260:169::-;;31378:6;31373:3;31366:19;31418:4;31413:3;31409:14;31394:29;;31356:73;;;;:::o;31435:305::-;;31494:20;31512:1;31494:20;:::i;:::-;31489:25;;31528:20;31546:1;31528:20;:::i;:::-;31523:25;;31682:1;31614:66;31610:74;31607:1;31604:81;31601:2;;;31688:18;;:::i;:::-;31601:2;31732:1;31729;31725:9;31718:16;;31479:261;;;;:::o;31746:185::-;;31803:20;31821:1;31803:20;:::i;:::-;31798:25;;31837:20;31855:1;31837:20;:::i;:::-;31832:25;;31876:1;31866:2;;31881:18;;:::i;:::-;31866:2;31923:1;31920;31916:9;31911:14;;31788:143;;;;:::o;31937:348::-;;32000:20;32018:1;32000:20;:::i;:::-;31995:25;;32034:20;32052:1;32034:20;:::i;:::-;32029:25;;32222:1;32154:66;32150:74;32147:1;32144:81;32139:1;32132:9;32125:17;32121:105;32118:2;;;32229:18;;:::i;:::-;32118:2;32277:1;32274;32270:9;32259:20;;31985:300;;;;:::o;32291:191::-;;32351:20;32369:1;32351:20;:::i;:::-;32346:25;;32385:20;32403:1;32385:20;:::i;:::-;32380:25;;32424:1;32421;32418:8;32415:2;;;32429:18;;:::i;:::-;32415:2;32474:1;32471;32467:9;32459:17;;32336:146;;;;:::o;32488:96::-;;32554:24;32572:5;32554:24;:::i;:::-;32543:35;;32533:51;;;:::o;32590:104::-;;32664:24;32682:5;32664:24;:::i;:::-;32653:35;;32643:51;;;:::o;32700:90::-;;32777:5;32770:13;32763:21;32752:32;;32742:48;;;:::o;32796:77::-;;32862:5;32851:16;;32841:32;;;:::o;32879:137::-;;32958:5;32947:16;;32964:46;33004:5;32964:46;:::i;:::-;32937:79;;;:::o;33022:137::-;;33101:5;33090:16;;33107:46;33147:5;33107:46;:::i;:::-;33080:79;;;:::o;33165:126::-;;33242:42;33235:5;33231:54;33220:65;;33210:81;;;:::o;33297:77::-;;33363:5;33352:16;;33342:32;;;:::o;33380:86::-;;33455:4;33448:5;33444:16;33433:27;;33423:43;;;:::o;33472:156::-;;33570:52;33616:5;33570:52;:::i;:::-;33557:65;;33547:81;;;:::o;33634:128::-;;33732:24;33750:5;33732:24;:::i;:::-;33719:37;;33709:53;;;:::o;33768:137::-;;33862:37;33893:5;33862:37;:::i;:::-;33849:50;;33839:66;;;:::o;33911:137::-;;34005:37;34036:5;34005:37;:::i;:::-;33992:50;;33982:66;;;:::o;34054:117::-;;34143:22;34159:5;34143:22;:::i;:::-;34130:35;;34120:51;;;:::o;34177:121::-;;34268:24;34286:5;34268:24;:::i;:::-;34255:37;;34245:53;;;:::o;34304:307::-;34372:1;34382:113;34396:6;34393:1;34390:13;34382:113;;;34481:1;34476:3;34472:11;34466:18;34462:1;34457:3;34453:11;34446:39;34418:2;34415:1;34411:10;34406:15;;34382:113;;;34513:6;34510:1;34507:13;34504:2;;;34593:1;34584:6;34579:3;34575:16;34568:27;34504:2;34353:258;;;;:::o;34617:167::-;;34677:22;34693:5;34677:22;:::i;:::-;34668:31;;34721:4;34714:5;34711:15;34708:2;;;34729:18;;:::i;:::-;34708:2;34776:1;34769:5;34765:13;34758:20;;34658:126;;;:::o;34790:180::-;34838:77;34835:1;34828:88;34935:4;34932:1;34925:15;34959:4;34956:1;34949:15;34976:180;35024:77;35021:1;35014:88;35121:4;35118:1;35111:15;35145:4;35142:1;35135:15;35162:180;35210:77;35207:1;35200:88;35307:4;35304:1;35297:15;35331:4;35328:1;35321:15;35348:102;;35440:2;35436:7;35431:2;35424:5;35420:14;35416:28;35406:38;;35396:54;;;:::o;35456:118::-;35542:1;35535:5;35532:12;35522:2;;35548:18;;:::i;:::-;35522:2;35512:62;:::o;35580:118::-;35666:1;35659:5;35656:12;35646:2;;35672:18;;:::i;:::-;35646:2;35636:62;:::o;35704:122::-;35777:24;35795:5;35777:24;:::i;:::-;35770:5;35767:35;35757:2;;35816:1;35813;35806:12;35757:2;35747:79;:::o;35832:116::-;35902:21;35917:5;35902:21;:::i;:::-;35895:5;35892:32;35882:2;;35938:1;35935;35928:12;35882:2;35872:76;:::o;35954:122::-;36027:24;36045:5;36027:24;:::i;:::-;36020:5;36017:35;36007:2;;36066:1;36063;36056:12;36007:2;35997:79;:::o;36082:122::-;36155:24;36173:5;36155:24;:::i;:::-;36148:5;36145:35;36135:2;;36194:1;36191;36184:12;36135:2;36125:79;:::o;36210:118::-;36281:22;36297:5;36281:22;:::i;:::-;36274:5;36271:33;36261:2;;36318:1;36315;36308:12;36261:2;36251:77;:::o

Swarm Source

ipfs://b6901c93fc119e7f959b48537cdc3a9498fe44b169bb1b77c90a81ba0ede6570
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.