ETH Price: $2,163.65 (+0.13%)

Contract

0x87F6fAA87358B628498E8DCD4E30b0378fEaFD07
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Liquidate157941042022-10-21 4:30:351246 days ago1666326635IN
0x87F6fAA8...78fEaFD07
0 ETH0.0094321720.92796737
Recall All148710632022-05-30 6:26:161390 days ago1653891976IN
0x87F6fAA8...78fEaFD07
0 ETH0.0028267719.42202387
Withdraw148527042022-05-27 6:55:261393 days ago1653634526IN
0x87F6fAA8...78fEaFD07
0 ETH0.0256869936.10563914
Repay148526982022-05-27 6:53:261393 days ago1653634406IN
0x87F6fAA8...78fEaFD07
0 ETH0.0033619530.29582591
Harvest147407062022-05-09 5:53:521411 days ago1652075632IN
0x87F6fAA8...78fEaFD07
0 ETH0.0161083629.96977548
Withdraw147286062022-05-07 8:02:361413 days ago1651910556IN
0x87F6fAA8...78fEaFD07
0 ETH0.0052761229.56557933
Repay147285982022-05-07 8:00:541413 days ago1651910454IN
0x87F6fAA8...78fEaFD07
0 ETH0.0032973929.71406401
Harvest146319982022-04-22 2:24:551428 days ago1650594295IN
0x87F6fAA8...78fEaFD07
0 ETH0.0313361159.25184892
Harvest144739372022-03-28 9:37:521452 days ago1648460272IN
0x87F6fAA8...78fEaFD07
0 ETH0.007242431.05475647
Harvest143639732022-03-11 6:28:121470 days ago1646980092IN
0x87F6fAA8...78fEaFD07
0 ETH0.0054322823.29314787
Harvest141768622022-02-10 6:59:461499 days ago1644476386IN
0x87F6fAA8...78fEaFD07
0 ETH0.0108184845.87584831
Harvest140352112022-01-19 9:39:031520 days ago1642585143IN
0x87F6fAA8...78fEaFD07
0 ETH0.0164128268.56188507
Harvest139118592021-12-31 7:43:021540 days ago1640936582IN
0x87F6fAA8...78fEaFD07
0 ETH0.0165663870.24983791
Harvest138139672021-12-16 4:10:411555 days ago1639627841IN
0x87F6fAA8...78fEaFD07
0 ETH0.0145892761.86589424
Withdraw137378092021-12-04 4:33:291567 days ago1638592409IN
0x87F6fAA8...78fEaFD07
0 ETH0.0070802984.68039505
Repay137377962021-12-04 4:30:551567 days ago1638592255IN
0x87F6fAA8...78fEaFD07
0 ETH0.0090256481.35098724
Harvest137252892021-12-02 4:32:091569 days ago1638419529IN
0x87F6fAA8...78fEaFD07
0 ETH0.0209693788.92072521
Harvest136322192021-11-17 9:48:371583 days ago1637142517IN
0x87F6fAA8...78fEaFD07
0 ETH0.0211521188.35947758
Borrow136267882021-11-16 13:16:441584 days ago1637068604IN
0x87F6fAA8...78fEaFD07
0 ETH0.01906512128.58380093
Deposit136211602021-11-15 15:39:061585 days ago1636990746IN
0x87F6fAA8...78fEaFD07
0 ETH0.04519181193.06060165
Withdraw136189932021-11-15 7:23:181586 days ago1636960998IN
0x87F6fAA8...78fEaFD07
0 ETH0.03302766180
Repay136189872021-11-15 7:22:161586 days ago1636960936IN
0x87F6fAA8...78fEaFD07
0 ETH0.0284517180
Withdraw136189562021-11-15 7:16:051586 days ago1636960565IN
0x87F6fAA8...78fEaFD07
0 ETH0.0321219180
Repay136189472021-11-15 7:13:561586 days ago1636960436IN
0x87F6fAA8...78fEaFD07
0 ETH0.01997478180
Borrow135883992021-11-10 12:07:111590 days ago1636546031IN
0x87F6fAA8...78fEaFD07
0 ETH0.0175746116.4706686
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Fryer

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2021-08-30
*/

// Dependency file: @openzeppelin/contracts/math/Math.sol

// SPDX-License-Identifier: MIT

// pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}


// Dependency file: @openzeppelin/contracts/utils/ReentrancyGuard.sol


// pragma solidity >=0.6.0 <0.8.0;

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

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

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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


// Dependency file: @openzeppelin/contracts/utils/Address.sol


// pragma solidity >=0.6.2 <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;
        // solhint-disable-next-line no-inline-assembly
        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");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


// Dependency file: @openzeppelin/contracts/math/SafeMath.sol


// pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
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) {
        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) {
        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) {
        // 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) {
        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) {
        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) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        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) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @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. 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) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        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) {
        require(b > 0, "SafeMath: modulo by zero");
        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) {
        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.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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) {
        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) {
        require(b > 0, errorMessage);
        return a % b;
    }
}


// Dependency file: @openzeppelin/contracts/token/ERC20/IERC20.sol


// pragma solidity >=0.6.0 <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);
}


// Dependency file: contracts/interfaces/IChainlink.sol

// pragma solidity >=0.6.5 <0.8.0;
interface IChainlink {
  function latestAnswer() external view returns (int256);
}

// Dependency file: contracts/interfaces/IFryerConfig.sol

// pragma solidity >=0.6.5 <0.8.0;

interface IFryerConfig {
    function getConfigValue(bytes32 _name) external view returns (uint256);

    function PERCENT_DENOMINATOR() external view returns (uint256);

    function ZERO_ADDRESS() external view returns (address);
}


// Dependency file: contracts/interfaces/IVaultAdapter.sol

// pragma solidity >=0.6.5 <0.8.0;

/// Interface for all Vault Adapter implementations.
interface IVaultAdapter {

  /// @dev Gets the token that the adapter accepts.
  function token() external view returns (address);

  /// @dev The total value of the assets deposited into the vault.
  function totalValue() external view returns (uint256);

  /// @dev Deposits funds into the vault.
  ///
  /// @param _amount  the amount of funds to deposit.
  function deposit(uint256 _amount) external;

  /// @dev Attempts to withdraw funds from the wrapped vault.
  ///
  /// The amount withdrawn to the recipient may be less than the amount requested.
  ///
  /// @param _recipient the recipient of the funds.
  /// @param _amount    the amount of funds to withdraw.
  function withdraw(address _recipient, uint256 _amount) external;
}

// Dependency file: contracts/interfaces/IOven.sol

// pragma solidity >=0.6.5 <0.8.0;




interface IOven {
    function distribute (address origin, uint256 amount) external;
}

// Dependency file: contracts/interfaces/IMintableERC20.sol

// pragma solidity >=0.6.5 <0.8.0;


interface IMintableERC20 {
  function mint(address _recipient, uint256 _amount) external;
  function burnFrom(address account, uint256 amount) external;
  function lowerHasMinted(uint256 amount)external;
}


// Dependency file: contracts/interfaces/IDetailedERC20.sol

// pragma solidity >=0.6.5 <0.8.0;

interface IDetailedERC20 {
    function name() external view returns (string memory);

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

    function decimals() external view returns (uint8);
}


// Dependency file: contracts/interfaces/IERC3156FlashBorrower.sol

// pragma solidity >=0.6.0 <=0.8.0;


interface IERC3156FlashBorrower {

    /**
     * @dev Receive a flash loan.
     * @param initiator The initiator of the loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param fee The additional amount of tokens to repay.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
     */
    function onFlashLoan(
        address initiator,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external returns (bytes32);
}


// Dependency file: contracts/interfaces/IERC3156FlashLender.sol

// pragma solidity >=0.6.0 <=0.8.0;
// import "contracts/interfaces/IERC3156FlashBorrower.sol";


interface IERC3156FlashLender {

    /**
     * @dev The amount of currency available to be lended.
     * @param token The loan currency.
     * @return The amount of `token` that can be borrowed.
     */
    function maxFlashLoan(
        address token
    ) external view returns (uint256);

    /**
     * @dev The fee to be charged for a given loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @return The amount of `token` to be charged for the loan, on top of the returned principal.
     */
    function flashFee(
        address token,
        uint256 amount
    ) external view returns (uint256);

    /**
     * @dev Initiate a flash loan.
     * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     */
    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external returns (bool);
}

// Dependency file: contracts/libraries/Upgradable.sol

// pragma solidity >=0.6.5 <0.8.0;

contract UpgradableProduct {
    address public impl;

    event ImplChanged(address indexed _oldImpl, address indexed _newImpl);

    constructor() public {
        impl = msg.sender;
    }

    modifier requireImpl() {
        require(msg.sender == impl, "FORBIDDEN");
        _;
    }

    function upgradeImpl(address _newImpl) public requireImpl {
        require(_newImpl != address(0), "INVALID_ADDRESS");
        require(_newImpl != impl, "NO_CHANGE");
        address lastImpl = impl;
        impl = _newImpl;
        emit ImplChanged(lastImpl, _newImpl);
    }
}

contract UpgradableGovernance {
    address public governor;

    event GovernorChanged(
        address indexed _oldGovernor,
        address indexed _newGovernor
    );

    constructor() public {
        governor = msg.sender;
    }

    modifier requireGovernor() {
        require(msg.sender == governor, "FORBIDDEN");
        _;
    }

    function upgradeGovernance(address _newGovernor) public requireGovernor {
        require(_newGovernor != address(0), "INVALID_ADDRESS");
        require(_newGovernor != governor, "NO_CHANGE");
        address lastGovernor = governor;
        governor = _newGovernor;
        emit GovernorChanged(lastGovernor, _newGovernor);
    }
}


// Dependency file: contracts/libraries/FixedPointMath.sol

// pragma solidity >=0.6.5 <0.8.0;


library FixedPointMath {
  uint256 public constant DECIMALS = 18;
  uint256 public constant SCALAR = 10**DECIMALS;

  struct uq192x64 {
    uint256 x;
  }

  function fromU256(uint256 value) internal pure returns (uq192x64 memory) {
    uint256 x;
    require(value == 0 || (x = value * SCALAR) / SCALAR == value);
    return uq192x64(x);
  }

  function maximumValue() internal pure returns (uq192x64 memory) {
    return uq192x64(uint256(-1));
  }

  function add(uq192x64 memory self, uq192x64 memory value) internal pure returns (uq192x64 memory) {
    uint256 x;
    require((x = self.x + value.x) >= self.x);
    return uq192x64(x);
  }

  function add(uq192x64 memory self, uint256 value) internal pure returns (uq192x64 memory) {
    return add(self, fromU256(value));
  }

  function sub(uq192x64 memory self, uq192x64 memory value) internal pure returns (uq192x64 memory) {
    uint256 x;
    require((x = self.x - value.x) <= self.x);
    return uq192x64(x);
  }

  function sub(uq192x64 memory self, uint256 value) internal pure returns (uq192x64 memory) {
    return sub(self, fromU256(value));
  }

  function mul(uq192x64 memory self, uint256 value) internal pure returns (uq192x64 memory) {
    uint256 x;
    require(value == 0 || (x = self.x * value) / value == self.x);
    return uq192x64(x);
  }

  function div(uq192x64 memory self, uint256 value) internal pure returns (uq192x64 memory) {
    require(value != 0);
    return uq192x64(self.x / value);
  }

  function cmp(uq192x64 memory self, uq192x64 memory value) internal pure returns (int256) {
    if (self.x < value.x) {
      return -1;
    }

    if (self.x > value.x) {
      return 1;
    }

    return 0;
  }

  function decode(uq192x64 memory self) internal pure returns (uint256) {
    return self.x / SCALAR;
  }
}

// Dependency file: contracts/libraries/TransferHelper.sol

// pragma solidity >=0.6.5 <0.8.0;

library TransferHelper {
    function safeApprove(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
    }
}


// Dependency file: contracts/libraries/Vault.sol

// pragma solidity >=0.6.5 <0.8.0;

// import '/Users/sg99022ml/Desktop/chfry-protocol-internal/node_modules/@openzeppelin/contracts/math/SafeMath.sol';
// import '/Users/sg99022ml/Desktop/chfry-protocol-internal/node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol';
// import 'contracts/interfaces/IVaultAdapter.sol';
// import 'contracts/libraries/TransferHelper.sol';

/// @title Pool
///
/// @dev A library which provides the Vault data struct and associated functions.
library Vault {
	using Vault for Data;
	using Vault for List;
	using TransferHelper for address;
	using SafeMath for uint256;

	struct Data {
		IVaultAdapter adapter;
		uint256 totalDeposited;
	}

	struct List {
		Data[] elements;
	}

	/// @dev Gets the total amount of assets deposited in the vault.
	///
	/// @return the total assets.
	function totalValue(Data storage _self) internal view returns (uint256) {
		return _self.adapter.totalValue();
	}

	/// @dev Gets the token that the vault accepts.
	///
	/// @return the accepted token.
	function token(Data storage _self) internal view returns (address) {
		return _self.adapter.token();
	}

	/// @dev Deposits funds from the caller into the vault.
	///
	/// @param _amount the amount of funds to deposit.
	function deposit(Data storage _self, uint256 _amount) internal returns (uint256) {
		// Push the token that the vault accepts onto the stack to save gas.
		address _token = _self.token();
		_token.safeTransfer(address(_self.adapter), _amount);
		_self.adapter.deposit(_amount);
		_self.totalDeposited = _self.totalDeposited.add(_amount);

		return _amount;
	}

	/// @dev Withdraw deposited funds from the vault.
	///
	/// @param _recipient the account to withdraw the tokens to.
	/// @param _amount    the amount of tokens to withdraw.
	function withdraw(
		Data storage _self,
		address _recipient,
		uint256 _amount
	) internal returns (uint256, uint256) {
		(uint256 _withdrawnAmount, uint256 _decreasedValue) = _self.directWithdraw(_recipient, _amount);
		_self.totalDeposited = _self.totalDeposited.sub(_decreasedValue);
		return (_withdrawnAmount, _decreasedValue);
	}

	/// @dev Directly withdraw deposited funds from the vault.
	///
	/// @param _recipient the account to withdraw the tokens to.
	/// @param _amount    the amount of tokens to withdraw.
	function directWithdraw(
		Data storage _self,
		address _recipient,
		uint256 _amount
	) internal returns (uint256, uint256) {
		address _token = _self.token();

		uint256 _startingBalance = IERC20(_token).balanceOf(_recipient);
		uint256 _startingTotalValue = _self.totalValue();

		_self.adapter.withdraw(_recipient, _amount);

		uint256 _endingBalance = IERC20(_token).balanceOf(_recipient);
		uint256 _withdrawnAmount = _endingBalance.sub(_startingBalance);

		uint256 _endingTotalValue = _self.totalValue();
		uint256 _decreasedValue = _startingTotalValue.sub(_endingTotalValue);

		return (_withdrawnAmount, _decreasedValue);
	}

	/// @dev Withdraw all the deposited funds from the vault.
	///
	/// @param _recipient the account to withdraw the tokens to.
	function withdrawAll(Data storage _self, address _recipient) internal returns (uint256, uint256) {
		return _self.withdraw(_recipient, _self.totalDeposited);
	}

	/// @dev Harvests yield from the vault.
	///
	/// @param _recipient the account to withdraw the harvested yield to.
	function harvest(Data storage _self, address _recipient) internal returns (uint256, uint256) {
		if (_self.totalValue() <= _self.totalDeposited) {
			return (0, 0);
		}
		uint256 _withdrawAmount = _self.totalValue().sub(_self.totalDeposited);
		return _self.directWithdraw(_recipient, _withdrawAmount);
	}

	/// @dev Adds a element to the list.
	///
	/// @param _element the element to add.
	function push(List storage _self, Data memory _element) internal {
		for (uint256 i = 0; i < _self.elements.length; i++) {
			// Avoid duplicated adapter
			require(address(_element.adapter) != address(_self.elements[i].adapter), '!Repeat adapter');
		}
		_self.elements.push(_element);
	}

	/// @dev Gets a element from the list.
	///
	/// @param _index the index in the list.
	///
	/// @return the element at the specified index.
	function get(List storage _self, uint256 _index) internal view returns (Data storage) {
		return _self.elements[_index];
	}

	/// @dev Gets the last element in the list.
	///
	/// This function will revert if there are no elements in the list.
	///
	/// @return the last element in the list.
	function last(List storage _self) internal view returns (Data storage) {
		return _self.elements[_self.lastIndex()];
	}

	/// @dev Gets the index of the last element in the list.
	///
	/// This function will revert if there are no elements in the list.
	///
	/// @return the index of the last element.
	function lastIndex(List storage _self) internal view returns (uint256) {
		uint256 _length = _self.length();
		return _length.sub(1, 'Vault.List: empty');
	}

	/// @dev Gets the number of elements in the list.
	///
	/// @return the number of elements.
	function length(List storage _self) internal view returns (uint256) {
		return _self.elements.length;
	}
}


// Dependency file: contracts/libraries/ConfigNames.sol

// pragma solidity >=0.6.5 <0.8.0;

library ConfigNames {
    bytes32 public constant FRYER_LTV = bytes32("FRYER_LTV");
    bytes32 public constant FRYER_HARVEST_FEE = bytes32("FRYER_HARVEST_FEE");
    bytes32 public constant FRYER_VAULT_PERCENTAGE =
        bytes32("FRYER_VAULT_PERCENTAGE");

    bytes32 public constant FRYER_FLASH_FEE_PROPORTION =
        bytes32("FRYER_FLASH_FEE_PROPORTION");

    bytes32 public constant PRIVATE = bytes32("PRIVATE");
    bytes32 public constant STAKE = bytes32("STAKE");
}


// Dependency file: contracts/libraries/CDP.sol

// pragma solidity >=0.6.5 <0.8.0;

// import '/Users/sg99022ml/Desktop/chfry-protocol-internal/node_modules/@openzeppelin/contracts/math/SafeMath.sol';
// import 'contracts/libraries/FixedPointMath.sol';
// import 'contracts/libraries/TransferHelper.sol';
// import 'contracts/libraries/ConfigNames.sol';
// import 'contracts/interfaces/IFryerConfig.sol';

library CDP {
	using CDP for Data;
	using FixedPointMath for FixedPointMath.uq192x64;
	using SafeMath for uint256;

	uint256 public constant MAXIMUM_COLLATERALIZATION_LIMIT = 4000000000000000000;

	struct Context {
		IFryerConfig fryerConfig;
		FixedPointMath.uq192x64 accumulatedYieldWeight;
	}

	struct Data {
		uint256 totalDeposited;
		uint256 totalDebt;
		uint256 totalCredit;
		uint256 lastDeposit;
		FixedPointMath.uq192x64 lastAccumulatedYieldWeight;
	}

	function update(Data storage _self, Context storage _ctx) internal {
		uint256 _earnedYield = _self.getEarnedYield(_ctx);
		if (_earnedYield > _self.totalDebt) {
			uint256 _currentTotalDebt = _self.totalDebt;
			_self.totalDebt = 0;
			_self.totalCredit = _earnedYield.sub(_currentTotalDebt);
		} else {
			_self.totalCredit = 0;
			_self.totalDebt = _self.totalDebt.sub(_earnedYield);
		}
		_self.lastAccumulatedYieldWeight = _ctx.accumulatedYieldWeight;
	}

	function checkHealth(
		Data storage _self,
		Context storage _ctx,
		string memory _msg
	) internal view {
		require(_self.isHealthy(_ctx), _msg);
	}

	function isHealthy(Data storage _self, Context storage _ctx) internal view returns (bool) {
		return collateralizationLimit(_ctx).cmp(_self.getCollateralizationRatio(_ctx)) <= 0;
	}

	function collateralizationLimit(Context storage _ctx) internal view returns (FixedPointMath.uq192x64 memory) {
		return
			FixedPointMath.uq192x64(
				MAXIMUM_COLLATERALIZATION_LIMIT.mul(_ctx.fryerConfig.getConfigValue(ConfigNames.FRYER_LTV)).div(
					_ctx.fryerConfig.PERCENT_DENOMINATOR()
				)
			);
	}

	function getUpdatedTotalDebt(Data storage _self, Context storage _ctx) internal view returns (uint256) {
		uint256 _unclaimedYield = _self.getEarnedYield(_ctx);
		if (_unclaimedYield == 0) {
			return _self.totalDebt;
		}

		uint256 _currentTotalDebt = _self.totalDebt;
		if (_unclaimedYield >= _currentTotalDebt) {
			return 0;
		}

		return _currentTotalDebt.sub(_unclaimedYield);
	}

	function getUpdatedTotalCredit(Data storage _self, Context storage _ctx) internal view returns (uint256) {
		uint256 _unclaimedYield = _self.getEarnedYield(_ctx);
		if (_unclaimedYield == 0) {
			return _self.totalCredit;
		}

		uint256 _currentTotalDebt = _self.totalDebt;
		if (_unclaimedYield <= _currentTotalDebt) {
			return 0;
		}

		return _self.totalCredit.add(_unclaimedYield.sub(_currentTotalDebt));
	}

	function getEarnedYield(Data storage _self, Context storage _ctx) internal view returns (uint256) {
		FixedPointMath.uq192x64 memory _currentAccumulatedYieldWeight = _ctx.accumulatedYieldWeight;
		FixedPointMath.uq192x64 memory _lastAccumulatedYieldWeight = _self.lastAccumulatedYieldWeight;

		if (_currentAccumulatedYieldWeight.cmp(_lastAccumulatedYieldWeight) == 0) {
			return 0;
		}

		return _currentAccumulatedYieldWeight.sub(_lastAccumulatedYieldWeight).mul(_self.totalDeposited).decode();
	}

	function getCollateralizationRatio(Data storage _self, Context storage _ctx)
		internal
		view
		returns (FixedPointMath.uq192x64 memory)
	{
		uint256 _totalDebt = _self.getUpdatedTotalDebt(_ctx);
		if (_totalDebt == 0) {
			return FixedPointMath.maximumValue();
		}
		return FixedPointMath.fromU256(_self.totalDeposited).div(_totalDebt);
	}
}


// Dependency file: @openzeppelin/contracts/utils/Context.sol


// pragma solidity >=0.6.0 <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 GSN 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 payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}


// Dependency file: @openzeppelin/contracts/token/ERC20/ERC20.sol


// pragma solidity >=0.6.0 <0.8.0;

// import "@openzeppelin/contracts/utils/Context.sol";
// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// import "@openzeppelin/contracts/math/SafeMath.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 guidelines: functions revert instead
 * of 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 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual 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 {_setupDecimals} is
     * called.
     *
     * 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 returns (uint8) {
        return _decimals;
    }

    /**
     * @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);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        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].add(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) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is 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);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(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:
     *
     * - `to` 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 = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(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);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(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 Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal virtual {
        _decimals = decimals_;
    }

    /**
     * @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 to 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 { }
}


// Dependency file: contracts/libraries/Convert.sol

// pragma solidity >=0.6.5 <0.8.0;

pragma experimental ABIEncoderV2;

// import '/Users/sg99022ml/Desktop/chfry-protocol-internal/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol';
// import '/Users/sg99022ml/Desktop/chfry-protocol-internal/node_modules/@openzeppelin/contracts/math/SafeMath.sol';

contract Convert {
	using SafeMath for uint256;

	function convertTokenAmount(
		address _fromToken,
		address _toToken,
		uint256 _fromAmount
	) public view returns (uint256 toAmount) {
		uint256 fromDecimals = uint256(ERC20(_fromToken).decimals());
		uint256 toDecimals = uint256(ERC20(_toToken).decimals());
		if (fromDecimals > toDecimals) {
			toAmount = _fromAmount.div(10**(fromDecimals.sub(toDecimals)));
		} else if (toDecimals > fromDecimals) {
			toAmount = _fromAmount.mul(10**(toDecimals.sub(fromDecimals)));
		} else {
			toAmount = _fromAmount;
		}
		return toAmount;
	}
}


// Dependency file: contracts/libraries/NoDelegateCall.sol

// pragma solidity >=0.6.5 <0.8.0;


/// @title Prevents delegatecall to a contract
/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract
abstract contract NoDelegateCall {
    /// @dev The original address of this contract
    address private immutable original;

    constructor() public {
        // Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode.
        // In other words, this variable won't change when it's checked at runtime.
        original = address(this);
    }

    /// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method,
    ///     and the use of immutable means the address bytes are copied in every place the modifier is used.
    function checkNotDelegateCall() private view {
        require(address(this) == original);
    }

    /// @notice Prevents delegatecall into the modified method
    modifier noDelegateCall() {
        checkNotDelegateCall();
        _;
    }
}

// Root file: contracts/Fryer.sol

pragma solidity >=0.6.5 <0.8.0;


contract Fryer is
    ReentrancyGuard,
    UpgradableProduct,
    IERC3156FlashLender,
    Convert,
    NoDelegateCall
{
    using CDP for CDP.Data;
    using FixedPointMath for FixedPointMath.uq192x64;
    using Vault for Vault.Data;
    using Vault for Vault.List;
    using TransferHelper for address;
    using SafeMath for uint256;
    using Address for address;

    event OvenUpdated(address indexed newOven);
    event ConfigUpdated(address indexed newConfig);
    event RewardsUpdated(address indexed reward);
    event EmergencyExitUpdated(bool indexed emergencyExit);
    event ActiveVaultUpdated(address indexed adapter);
    event FundsHarvested(
        uint256 indexed harvestedAmount,
        uint256 indexed decreasedValue
    );
    event FundsFlushed(uint256 indexed depositedAmount);
    event TokensDeposited(address indexed user, uint256 indexed amount);
    event TokensWithdrawn(
        address indexed user,
        uint256 indexed amount,
        uint256 withdrawnAmount,
        uint256 decreasedValue
    );
    event TokensRepaid(
        address indexed user,
        uint256 indexed parentAmount,
        uint256 indexed childAmount
    );
    event TokensLiquidated(
        address indexed user,
        uint256 indexed amount,
        uint256 withdrawnAmount,
        uint256 decreasedValue
    );
    event FundsRecalled(
        uint256 indexed vaultId,
        uint256 withdrawnAmount,
        uint256 decreasedValue
    );
    event UseFlashloan(
        address indexed user,
        address token,
        uint256 amount,
        uint256 fee
    );

    bytes32 public constant FLASH_CALLBACK_SUCCESS =
        keccak256("ERC3156FlashBorrower.onFlashLoan");

    // DAI/USDT/USDC
    address public token;

    // FiresToken
    address public friesToken;

    address public oven;

    address public rewards;

    uint256 public totalDeposited;

    uint256 public flushActivator;

    bool public initialized;

    bool public emergencyExit;

    CDP.Context private _ctx;

    mapping(address => CDP.Data) private _cdps;

    Vault.List private _vaults;

    address public _linkGasOracle;

    uint256 public pegMinimum;

    IFryerConfig public fryerConfig;

    constructor(
        address _token,
        address _friesToken,
        address _fryerConfig
    ) public {
        token = _token;
        friesToken = _friesToken;
        flushActivator = 100000 * 10**uint256(IDetailedERC20(token).decimals());
        fryerConfig = IFryerConfig(_fryerConfig);
        _ctx.fryerConfig = fryerConfig;
        _ctx.accumulatedYieldWeight = FixedPointMath.uq192x64(0);
    }

    modifier expectInitialized() {
        require(initialized, "not initialized.");
        _;
    }

    function setOven(address _oven) external requireImpl {
        require(
            _oven != fryerConfig.ZERO_ADDRESS(),
            "oven address cannot be 0x0."
        );
        oven = _oven;
        emit OvenUpdated(_oven);
    }

    function setConfig(address _config) external requireImpl {
        require(
            _config != fryerConfig.ZERO_ADDRESS(),
            "config address cannot be 0x0."
        );
        fryerConfig = IFryerConfig(_config);
        _ctx.fryerConfig = fryerConfig;
        emit ConfigUpdated(_config);
    }

    function setFlushActivator(uint256 _flushActivator) external requireImpl {
        flushActivator = _flushActivator;
    }

    function setRewards(address _rewards) external requireImpl {
        require(
            _rewards != fryerConfig.ZERO_ADDRESS(),
            "rewards address cannot be 0x0."
        );
        rewards = _rewards;
        emit RewardsUpdated(_rewards);
    }

    function setOracleAddress(address Oracle, uint256 peg)
        external
        requireImpl
    {
        _linkGasOracle = Oracle;
        pegMinimum = peg;
    }

    function setEmergencyExit(bool _emergencyExit) external requireImpl {
        emergencyExit = _emergencyExit;

        emit EmergencyExitUpdated(_emergencyExit);
    }

    function collateralizationLimit()
        external
        view
        returns (FixedPointMath.uq192x64 memory)
    {
        return CDP.collateralizationLimit(_ctx);
    }

    function initialize(address _adapter) external requireImpl {
        require(!initialized, "already initialized");
        require(
            oven != fryerConfig.ZERO_ADDRESS(),
            "cannot initialize oven address to 0x0"
        );
        require(
            rewards != fryerConfig.ZERO_ADDRESS(),
            "cannot initialize rewards address to 0x0"
        );
        _updateActiveVault(_adapter);
        initialized = true;
    }

    function migrate(address _adapter) external expectInitialized requireImpl {
        _updateActiveVault(_adapter);
    }

    function _updateActiveVault(address _adapter) internal {
        require(
            _adapter != fryerConfig.ZERO_ADDRESS(),
            "active vault address cannot be 0x0."
        );
        IVaultAdapter adapter = IVaultAdapter(_adapter);
        require(adapter.token() == token, "token mismatch.");
        _vaults.push(Vault.Data({adapter: adapter, totalDeposited: 0}));
        emit ActiveVaultUpdated(_adapter);
    }

    function harvest(uint256 _vaultId)
        external
        expectInitialized
        returns (uint256, uint256)
    {
        Vault.Data storage _vault = _vaults.get(_vaultId);

        (uint256 _harvestedAmount, uint256 _decreasedValue) =
            _vault.harvest(address(this));

        _incomeDistribution(_harvestedAmount);

        emit FundsHarvested(_harvestedAmount, _decreasedValue);

        return (_harvestedAmount, _decreasedValue);
    }

    function _incomeDistribution(uint256 amount) internal {
        if (amount > 0) {
            uint256 feeRate = fryerConfig.getConfigValue(ConfigNames.FRYER_HARVEST_FEE);
            uint256 _feeAmount =  amount.mul(feeRate).div(fryerConfig.PERCENT_DENOMINATOR());
            uint256 _distributeAmount = amount.sub(_feeAmount);

            if (totalDeposited > 0) {
                FixedPointMath.uq192x64 memory _weight =
                    FixedPointMath.fromU256(_distributeAmount).div(
                        totalDeposited
                    );
                _ctx.accumulatedYieldWeight = _ctx.accumulatedYieldWeight.add(
                    _weight
                );
            }

            if (_feeAmount > 0) {
                token.safeTransfer(rewards, _feeAmount);
            }

            if (_distributeAmount > 0) {
                _distributeToOven(_distributeAmount);
            }
        }
    }

    function recall(uint256 _vaultId, uint256 _amount)
        external
        nonReentrant
        expectInitialized
        returns (uint256, uint256)
    {
        return _recallFunds(_vaultId, _amount);
    }

    function recallAll(uint256 _vaultId)
        external
        nonReentrant
        expectInitialized
        returns (uint256, uint256)
    {
        Vault.Data storage _vault = _vaults.get(_vaultId);
        return _recallFunds(_vaultId, _vault.totalDeposited);
    }

    function flush() external nonReentrant expectInitialized returns (uint256) {
        require(!emergencyExit, "emergency pause enabled");

        return flushActiveVault();
    }

    function flushActiveVault() internal returns (uint256) {
        Vault.Data storage _activeVault = _vaults.last();
        uint256 balance = IERC20(token).balanceOf(address(this));
        uint256 ratio = fryerConfig.getConfigValue(ConfigNames.FRYER_VAULT_PERCENTAGE);
        uint256 pendingTotal =
            balance.add(_activeVault.totalDeposited).mul(ratio)
                .div(fryerConfig.PERCENT_DENOMINATOR());
        if (pendingTotal > _activeVault.totalDeposited) {
            uint256 _depositedAmount =
                _activeVault.deposit(
                    pendingTotal.sub(_activeVault.totalDeposited)
                );
            emit FundsFlushed(_depositedAmount);
            return _depositedAmount;
        } else {
            return 0;
        }
    }

    function deposit(uint256 _amount)
        external
        nonReentrant
        noDelegateCall
        noContractAllowed
        expectInitialized
    {
        require(!emergencyExit, "emergency pause enabled");

        CDP.Data storage _cdp = _cdps[msg.sender];
        _cdp.update(_ctx);

        token.safeTransferFrom(msg.sender, address(this), _amount);

        totalDeposited = totalDeposited.add(_amount);

        _cdp.totalDeposited = _cdp.totalDeposited.add(_amount);
        _cdp.lastDeposit = block.number;

        if (_amount >= flushActivator) {
            flushActiveVault();
        }

        emit TokensDeposited(msg.sender, _amount);
    }

    function withdraw(uint256 _amount)
        external
        nonReentrant
        noDelegateCall
        noContractAllowed
        expectInitialized
        returns (uint256, uint256)
    {
        CDP.Data storage _cdp = _cdps[msg.sender];
        require(block.number > _cdp.lastDeposit, "");

        _cdp.update(_ctx);

        (uint256 _withdrawnAmount, uint256 _decreasedValue) =
            _withdrawFundsTo(msg.sender, _amount);

        _cdp.totalDeposited = _cdp.totalDeposited.sub(
            _decreasedValue,
            "Exceeds withdrawable amount"
        );
        _cdp.checkHealth(
            _ctx,
            "Action blocked: unhealthy collateralization ratio"
        );
        if (_amount >= flushActivator) {
            flushActiveVault();
        }
        emit TokensWithdrawn(
            msg.sender,
            _amount,
            _withdrawnAmount,
            _decreasedValue
        );

        return (_withdrawnAmount, _decreasedValue);
    }

    function repay(uint256 _parentAmount, uint256 _childAmount)
        external
        nonReentrant
        noDelegateCall
        noContractAllowed
        onLinkCheck
        expectInitialized
    {
        CDP.Data storage _cdp = _cdps[msg.sender];
        _cdp.update(_ctx);

        if (_parentAmount > 0) {
            token.safeTransferFrom(msg.sender, address(this), _parentAmount);
            _distributeToOven(_parentAmount);
        }

        uint256 childAmount_ =
            convertTokenAmount(friesToken, token, _childAmount);
        // friesUsd convert USDT/DAI/USDC > 0
        if (childAmount_ > 0) {
            IMintableERC20(friesToken).burnFrom(msg.sender, _childAmount);
            IMintableERC20(friesToken).lowerHasMinted(_childAmount);
        } else {
            _childAmount = 0;
        }

        uint256 _totalAmount = _parentAmount.add(childAmount_);
        _cdp.totalDebt = _cdp.totalDebt.sub(_totalAmount);

        emit TokensRepaid(msg.sender, _parentAmount, _childAmount);
    }

    function liquidate(uint256 _amount)
        external
        nonReentrant
        noDelegateCall
        noContractAllowed
        onLinkCheck
        expectInitialized
        returns (uint256, uint256)
    {
        CDP.Data storage _cdp = _cdps[msg.sender];
        _cdp.update(_ctx);

        if (_amount > _cdp.totalDebt) {
            _amount = _cdp.totalDebt;
        }
        (uint256 _withdrawnAmount, uint256 _decreasedValue) =
            _withdrawFundsTo(address(this), _amount);
        _distributeToOven(_withdrawnAmount);

        _cdp.totalDeposited = _cdp.totalDeposited.sub(_decreasedValue);
        _cdp.totalDebt = _cdp.totalDebt.sub(_withdrawnAmount);
        emit TokensLiquidated(
            msg.sender,
            _amount,
            _withdrawnAmount,
            _decreasedValue
        );

        return (_withdrawnAmount, _decreasedValue);
    }

    function borrow(uint256 _amount)
        external
        nonReentrant
        noDelegateCall
        noContractAllowed
        onLinkCheck
        expectInitialized
    {
        CDP.Data storage _cdp = _cdps[msg.sender];
        _cdp.update(_ctx);

        uint256 _totalCredit = _cdp.totalCredit;

        if (_totalCredit < _amount) {
            uint256 _remainingAmount = _amount.sub(_totalCredit);
            _cdp.totalDebt = _cdp.totalDebt.add(_remainingAmount);
            _cdp.totalCredit = 0;
            _cdp.checkHealth(_ctx, "Loan-to-value ratio breached");
        } else {
            _cdp.totalCredit = _totalCredit.sub(_amount);
        }
        uint256 mint = convertTokenAmount(token, friesToken, _amount);
        IMintableERC20(friesToken).mint(msg.sender, mint);
        if (_amount >= flushActivator) {
            flushActiveVault();
        }
    }

    function vaultCount() external view returns (uint256) {
        return _vaults.length();
    }

    function getVaultAdapter(uint256 _vaultId)
        external
        view
        returns (IVaultAdapter)
    {
        Vault.Data storage _vault = _vaults.get(_vaultId);
        return _vault.adapter;
    }

    function getVaultTotalDeposited(uint256 _vaultId)
        external
        view
        returns (uint256)
    {
        Vault.Data storage _vault = _vaults.get(_vaultId);
        return _vault.totalDeposited;
    }

    function getCdpTotalDeposited(address _account)
        external
        view
        returns (uint256)
    {
        CDP.Data storage _cdp = _cdps[_account];
        return _cdp.totalDeposited;
    }

    function getCdpTotalDebt(address _account) external view returns (uint256) {
        CDP.Data storage _cdp = _cdps[_account];
        return _cdp.getUpdatedTotalDebt(_ctx);
    }

    function getCdpTotalCredit(address _account)
        external
        view
        returns (uint256)
    {
        CDP.Data storage _cdp = _cdps[_account];
        return _cdp.getUpdatedTotalCredit(_ctx);
    }

    function getCdpLastDeposit(address _account)
        external
        view
        returns (uint256)
    {
        CDP.Data storage _cdp = _cdps[_account];
        return _cdp.lastDeposit;
    }

    function _distributeToOven(uint256 amount) internal {
        token.safeApprove(oven, amount);
        IOven(oven).distribute(address(this), amount);
        uint256 mintAmount = convertTokenAmount(token, friesToken, amount);
        IMintableERC20(friesToken).lowerHasMinted(mintAmount);
    }

    modifier onLinkCheck() {
        if (pegMinimum > 0) {
            uint256 oracleAnswer =
                uint256(IChainlink(_linkGasOracle).latestAnswer());
            require(oracleAnswer > pegMinimum, "off peg limitation");
        }
        _;
    }

    modifier noContractAllowed() {
        require(
            !address(msg.sender).isContract() && msg.sender == tx.origin,
            "Sorry we do not accept contract!"
        );
        _;
    }

    function _recallFunds(uint256 _vaultId, uint256 _amount)
        internal
        returns (uint256, uint256)
    {
        require(
            emergencyExit ||
                msg.sender == impl ||
                _vaultId != _vaults.lastIndex(),
            "not an emergency, not governance, and user does not have permission to recall funds from active vault"
        );

        Vault.Data storage _vault = _vaults.get(_vaultId);
        (uint256 _withdrawnAmount, uint256 _decreasedValue) =
            _vault.withdraw(address(this), _amount);

        emit FundsRecalled(_vaultId, _withdrawnAmount, _decreasedValue);

        return (_withdrawnAmount, _decreasedValue);
    }

    function _withdrawFundsTo(address _recipient, uint256 _amount)
        internal
        returns (uint256, uint256)
    {
        uint256 _bufferedAmount =
            Math.min(_amount, IERC20(token).balanceOf(address(this)));

        if (_recipient != address(this)) {
            token.safeTransfer(_recipient, _bufferedAmount);
        }

        uint256 _totalWithdrawn = _bufferedAmount;
        uint256 _totalDecreasedValue = _bufferedAmount;

        uint256 _remainingAmount = _amount.sub(_bufferedAmount);
        if (_remainingAmount > 0) {
            Vault.Data storage _activeVault = _vaults.last();
            (uint256 _withdrawAmount, uint256 _decreasedValue) =
                _activeVault.withdraw(_recipient, _remainingAmount);

            _totalWithdrawn = _totalWithdrawn.add(_withdrawAmount);
            _totalDecreasedValue = _totalDecreasedValue.add(_decreasedValue);
        }

        totalDeposited = totalDeposited.sub(_totalDecreasedValue);

        return (_totalWithdrawn, _totalDecreasedValue);
    }

    // flash

    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token_,
        uint256 amount,
        bytes calldata data
    ) external override returns (bool) {
        require(token == token_, "FlashLender: Unsupported currency");
        uint256 _fee = _flashFee(amount);
        token.safeTransfer(address(receiver), amount);
        require(
            receiver.onFlashLoan(msg.sender, token, amount, _fee, data) ==
                FLASH_CALLBACK_SUCCESS,
            "FlashLender: Callback failed"
        );
        token.safeTransferFrom(
            address(receiver),
            address(this),
            amount.add(_fee)
        );

        _incomeDistribution(_fee);
        emit UseFlashloan(tx.origin, token, amount, _fee);
        return true;
    }

    function flashFee(address token_, uint256 amount)
        external
        view
        override
        returns (uint256)
    {
        require(token == token_, "FlashLender: Unsupported currency");
        return _flashFee(amount);
    }

    function _flashFee(uint256 amount) internal view returns (uint256) {
        uint256 prop =
            fryerConfig.getConfigValue(ConfigNames.FRYER_FLASH_FEE_PROPORTION);
        uint256 PERCENT_DENOMINATOR = fryerConfig.PERCENT_DENOMINATOR();
        return amount.mul(prop).div(PERCENT_DENOMINATOR);
    }

    /**
     * @dev The amount of currency available to be lended.
     * @param token_ The loan currency.
     * @return The amount of `token` that can be borrowed.
     */
    function maxFlashLoan(address token_)
        external
        view
        override
        returns (uint256)
    {
        if (token == token_) {
            return IERC20(token).balanceOf(address(this));
        } else {
            return 0;
        }
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_friesToken","type":"address"},{"internalType":"address","name":"_fryerConfig","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"}],"name":"ActiveVaultUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newConfig","type":"address"}],"name":"ConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"emergencyExit","type":"bool"}],"name":"EmergencyExitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"depositedAmount","type":"uint256"}],"name":"FundsFlushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"harvestedAmount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"FundsHarvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"FundsRecalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldImpl","type":"address"},{"indexed":true,"internalType":"address","name":"_newImpl","type":"address"}],"name":"ImplChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOven","type":"address"}],"name":"OvenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reward","type":"address"}],"name":"RewardsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"TokensLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"parentAmount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"childAmount","type":"uint256"}],"name":"TokensRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"TokensWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"UseFlashloan","type":"event"},{"inputs":[],"name":"FLASH_CALLBACK_SUCCESS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_linkGasOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateralizationLimit","outputs":[{"components":[{"internalType":"uint256","name":"x","type":"uint256"}],"internalType":"struct FixedPointMath.uq192x64","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"},{"internalType":"address","name":"_toToken","type":"address"},{"internalType":"uint256","name":"_fromAmount","type":"uint256"}],"name":"convertTokenAmount","outputs":[{"internalType":"uint256","name":"toAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyExit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flush","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flushActivator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"friesToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fryerConfig","outputs":[{"internalType":"contract IFryerConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpLastDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpTotalCredit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpTotalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getVaultAdapter","outputs":[{"internalType":"contract IVaultAdapter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getVaultTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"harvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"impl","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adapter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"liquidate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adapter","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oven","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pegMinimum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recall","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"recallAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parentAmount","type":"uint256"},{"internalType":"uint256","name":"_childAmount","type":"uint256"}],"name":"repay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_config","type":"address"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_emergencyExit","type":"bool"}],"name":"setEmergencyExit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_flushActivator","type":"uint256"}],"name":"setFlushActivator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"Oracle","type":"address"},{"internalType":"uint256","name":"peg","type":"uint256"}],"name":"setOracleAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oven","type":"address"}],"name":"setOven","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newImpl","type":"address"}],"name":"upgradeImpl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b50604051620041c7380380620041c783398101604081905262000034916200014c565b600160008190558054336001600160a01b0319918216179091553060601b6080526002805482166001600160a01b03868116919091179182905560038054909316858216179092556040805163313ce56760e01b81529051919092169163313ce567916004808301926020929190829003018186803b158015620000b757600080fd5b505afa158015620000cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f291906200019f565b60ff16600a90810a620186a002600755600f80546001600160a01b03199081166001600160a01b03948516179182905560098054929094169116179091556040805160208101909152600090819052905550620001e29050565b60008060006060848603121562000161578283fd5b83516200016e81620001c9565b60208501519093506200018181620001c9565b60408501519092506200019481620001c9565b809150509250925092565b600060208284031215620001b1578081fd5b815160ff81168114620001c2578182fd5b9392505050565b6001600160a01b0381168114620001df57600080fd5b50565b60805160601c613fc76200020060003980611e385250613fc76000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80639a9af22111610151578063c5ebeaec116100c3578063ec38a86211610087578063ec38a862146104eb578063f0d787a3146104fe578063fc00e8a014610506578063fc0c546a14610519578063fefdc5d114610521578063ff50abdc1461053457610269565b8063c5ebeaec1461048c578063ce5494bb1461049f578063d8aed145146104b2578063d9d98ce4146104c5578063ddc63262146104d857610269565b8063a7c6a10011610115578063a7c6a10014610430578063aa6e043414610438578063aaf166601461044b578063b6b55f251461045e578063bb39ef8214610471578063c4d66de81461047957610269565b80639a9af221146103f25780639d908f5a146104055780639ec5a8941461040d578063a005fda314610415578063a1e401a91461041d57610269565b80634c3a8e02116101ea5780636b9f96ea116101ae5780636b9f96ea146103ac57806375a356cc146103b45780637857a7c6146103c75780637b79b23e146103cf5780638abf6077146103d757806393ce9d23146103df57610269565b80634c3a8e02146103585780635641ec031461036b5780635a9b5e92146103735780635cffe9de14610386578063613255ab1461039957610269565b80632e1a7d4d116102315780632e1a7d4d146102e75780633847f03814610308578063415f12401461031d57806345ee0755146103305780634aaf7c651461034357610269565b8063158ef93e1461026e5780631a2f13631461028c57806320e3dbd4146102a157806322c37b75146102b45780632670fdd8146102c7575b600080fd5b61027661053c565b60405161028391906138a4565b60405180910390f35b61029f61029a3660046135d6565b610545565b005b61029f6102af3660046135d6565b61061e565b61029f6102c2366004613763565b61075d565b6102da6102d5366004613763565b61078c565b60405161028391906137d9565b6102fa6102f5366004613763565b6107ad565b604051610283929190613f03565b610310610955565b60405161028391906138af565b6102fa61032b366004613763565b61095b565b61029f61033e366004613679565b610b2b565b61034b610b9a565b6040516102839190613ef9565b6102fa610366366004613763565b610bb2565b610276610c2c565b61029f61038136600461364e565b610c3a565b6102766103943660046136c9565b610c8a565b6103106103a73660046135d6565b610e2d565b610310610ed5565b6103106103c236600461360e565b610f5b565b6102da61109e565b6103106110ad565b6102da6110d1565b61029f6103ed3660046135d6565b6110e0565b6103106104003660046135d6565b61120b565b6102da611229565b6102da611238565b6102da611247565b61031061042b3660046135d6565b611256565b610310611271565b6103106104463660046135d6565b61127d565b610310610459366004613763565b6112a7565b61029f61046c366004613763565b6112c0565b6102da61140a565b61029f6104873660046135d6565b611419565b61029f61049a366004613763565b6115e7565b61029f6104ad3660046135d6565b611860565b61029f6104c036600461377b565b6118b8565b6103106104d336600461364e565b611b7c565b6102fa6104e6366004613763565b611bbe565b61029f6104f93660046135d6565b611c46565b610310611d71565b6103106105143660046135d6565b611d77565b6102da611d9a565b6102fa61052f36600461377b565b611da9565b610310611e00565b60085460ff1681565b6001546001600160a01b031633146105785760405162461bcd60e51b815260040161056f90613bc3565b60405180910390fd5b6001600160a01b03811661059e5760405162461bcd60e51b815260040161056f90613922565b6001546001600160a01b03828116911614156105cc5760405162461bcd60e51b815260040161056f90613c2b565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907faad46b89531ed10d02d926f4d6bfe234a6126e3fffc02d3b07167575f9c1433790600090a35050565b6001546001600160a01b031633146106485760405162461bcd60e51b815260040161056f90613bc3565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561069657600080fd5b505afa1580156106aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ce91906135f2565b6001600160a01b0316816001600160a01b031614156106ff5760405162461bcd60e51b815260040161056f90613a77565b600f80546001600160a01b038084166001600160a01b031992831681179384905560098054909316939091169290921790556040517f89b8aa6a0bad94aca607eff7d3631d67e0e67b2c775044f517a269ae8b6662af90600090a250565b6001546001600160a01b031633146107875760405162461bcd60e51b815260040161056f90613bc3565b600755565b60008061079a600c84611e06565b546001600160a01b03169150505b919050565b600080600260005414156107d35760405162461bcd60e51b815260040161056f90613e6d565b60026000556107e0611e2d565b6107e933611e64565b1580156107f557503332145b6108115760405162461bcd60e51b815260040161056f90613a42565b60085460ff166108335760405162461bcd60e51b815260040161056f90613d80565b336000908152600b60205260409020600381015443116108655760405162461bcd60e51b815260040161056f90613de1565b610870816009611e6a565b60008061087d3387611ecd565b60408051808201909152601b81527f4578636565647320776974686472617761626c6520616d6f756e740000000000602082015285549294509092506108c591908390611ff8565b8355604080516060810190915260318082526108ee91600991613f616020830139859190612024565b6007548610610901576108ff612053565b505b85336001600160a01b03167fb3ad69dc1d2c6b1f5f5b0927ffd8ee8f1437a156253c8f6dccc75e6f8e4fd38b848460405161093d929190613f03565b60405180910390a36001600055909590945092505050565b600e5481565b600080600260005414156109815760405162461bcd60e51b815260040161056f90613e6d565b600260005561098e611e2d565b61099733611e64565b1580156109a357503332145b6109bf5760405162461bcd60e51b815260040161056f90613a42565b600e5415610a6957600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd916004808301926020929190829003018186803b158015610a0c57600080fd5b505afa158015610a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4491906136b1565b9050600e548111610a675760405162461bcd60e51b815260040161056f90613ea4565b505b60085460ff16610a8b5760405162461bcd60e51b815260040161056f90613d80565b336000908152600b60205260409020610aa5816009611e6a565b8060010154841115610ab957806001015493505b600080610ac63087611ecd565b91509150610ad3826122b1565b8254610adf90826123b8565b83556001830154610af090836123b8565b6001840155604051869033907f3ea051727656be6fd11c2260f244f29ff3c70d1fb077bfa73e89d554e9bb95c79061093d9086908690613f03565b6001546001600160a01b03163314610b555760405162461bcd60e51b815260040161056f90613bc3565b6008805461ff001916610100831515908102919091179091556040517ff0064f2efd0da4bc63eecf2e75590fe8a308eaa526a51c334e50eec09a71104990600090a250565b610ba26135c3565b610bac60096123e0565b90505b90565b60008060026000541415610bd85760405162461bcd60e51b815260040161056f90613e6d565b600260005560085460ff16610bff5760405162461bcd60e51b815260040161056f90613d80565b6000610c0c600c85611e06565b9050610c1c848260010154612522565b6001600055909590945092505050565b600854610100900460ff1681565b6001546001600160a01b03163314610c645760405162461bcd60e51b815260040161056f90613bc3565b600d80546001600160a01b0319166001600160a01b039390931692909217909155600e55565b6002546000906001600160a01b03868116911614610cba5760405162461bcd60e51b815260040161056f9061394b565b6000610cc5856125de565b600254909150610cdf906001600160a01b03168887612725565b6002546040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9916001600160a01b03808b16926323e30c8b92610d3c9233929116908b9088908c908c906004016137ed565b602060405180830381600087803b158015610d5657600080fd5b505af1158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e91906136b1565b14610dab5760405162461bcd60e51b815260040161056f90613d20565b610dce8730610dba8885612813565b6002546001600160a01b0316929190612838565b610dd781612921565b60025460405132917fedc5fb7867c40a2d7e1268a077f82bc782a7302f52cfe37eb01eb0cab9c8ffff91610e18916001600160a01b03169089908690613883565b60405180910390a25060019695505050505050565b6002546000906001600160a01b0383811691161415610ecd576002546040516370a0823160e01b81526001600160a01b03909116906370a0823190610e769030906004016137d9565b60206040518083038186803b158015610e8e57600080fd5b505afa158015610ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec691906136b1565b90506107a8565b5060006107a8565b600060026000541415610efa5760405162461bcd60e51b815260040161056f90613e6d565b600260005560085460ff16610f215760405162461bcd60e51b815260040161056f90613d80565b600854610100900460ff1615610f495760405162461bcd60e51b815260040161056f90613df2565b610f51612053565b9050600160005590565b600080846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9757600080fd5b505afa158015610fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcf919061379c565b60ff1690506000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561100f57600080fd5b505afa158015611023573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611047919061379c565b60ff169050808211156110725761106b61106183836123b8565b8590600a0a612ade565b9250611095565b818111156110915761106b61108782846123b8565b8590600a0a612b10565b8392505b50509392505050565b6003546001600160a01b031681565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b6001546001600160a01b031681565b6001546001600160a01b0316331461110a5760405162461bcd60e51b815260040161056f90613bc3565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561115857600080fd5b505afa15801561116c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119091906135f2565b6001600160a01b0316816001600160a01b031614156111c15760405162461bcd60e51b815260040161056f90613b28565b600480546001600160a01b0319166001600160a01b0383169081179091556040517f88b3009fd17aa3fbf19d233400b10b7282db2bfa2a996dba8bc11c07b98d521090600090a250565b6001600160a01b03166000908152600b602052604090206003015490565b6004546001600160a01b031681565b6005546001600160a01b031681565b600d546001600160a01b031681565b6001600160a01b03166000908152600b602052604090205490565b6000610bac600c612b4a565b6001600160a01b0381166000908152600b602052604081206112a0816009612b4e565b9392505050565b6000806112b5600c84611e06565b600101549392505050565b600260005414156112e35760405162461bcd60e51b815260040161056f90613e6d565b60026000556112f0611e2d565b6112f933611e64565b15801561130557503332145b6113215760405162461bcd60e51b815260040161056f90613a42565b60085460ff166113435760405162461bcd60e51b815260040161056f90613d80565b600854610100900460ff161561136b5760405162461bcd60e51b815260040161056f90613df2565b336000908152600b60205260409020611385816009611e6a565b60025461139d906001600160a01b0316333085612838565b6006546113aa9083612813565b60065580546113b99083612813565b815543600382015560075482106113d4576113d2612053565b505b604051829033907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e90600090a350506001600055565b600f546001600160a01b031681565b6001546001600160a01b031633146114435760405162461bcd60e51b815260040161056f90613bc3565b60085460ff16156114665760405162461bcd60e51b815260040161056f90613b96565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b457600080fd5b505afa1580156114c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ec91906135f2565b6004546001600160a01b039081169116141561151a5760405162461bcd60e51b815260040161056f90613be6565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561156857600080fd5b505afa15801561157c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a091906135f2565b6005546001600160a01b03908116911614156115ce5760405162461bcd60e51b815260040161056f906139c3565b6115d781612b98565b506008805460ff19166001179055565b6002600054141561160a5760405162461bcd60e51b815260040161056f90613e6d565b6002600055611617611e2d565b61162033611e64565b15801561162c57503332145b6116485760405162461bcd60e51b815260040161056f90613a42565b600e54156116f257600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd916004808301926020929190829003018186803b15801561169557600080fd5b505afa1580156116a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cd91906136b1565b9050600e5481116116f05760405162461bcd60e51b815260040161056f90613ea4565b505b60085460ff166117145760405162461bcd60e51b815260040161056f90613d80565b336000908152600b6020526040902061172e816009611e6a565b6002810154828110156117ad57600061174784836123b8565b60018401549091506117599082612813565b60018401556000600284015560408051808201909152601c81527f4c6f616e2d746f2d76616c756520726174696f2062726561636865640000000060208201526117a7908490600990612024565b506117bd565b6117b781846123b8565b60028301555b6002546003546000916117dd916001600160a01b03918216911686610f5b565b6003546040516340c10f1960e01b81529192506001600160a01b0316906340c10f19906118109033908590600401613846565b600060405180830381600087803b15801561182a57600080fd5b505af115801561183e573d6000803e3d6000fd5b50505050600754841061185557611853612053565b505b505060016000555050565b60085460ff166118825760405162461bcd60e51b815260040161056f90613d80565b6001546001600160a01b031633146118ac5760405162461bcd60e51b815260040161056f90613bc3565b6118b581612b98565b50565b600260005414156118db5760405162461bcd60e51b815260040161056f90613e6d565b60026000556118e8611e2d565b6118f133611e64565b1580156118fd57503332145b6119195760405162461bcd60e51b815260040161056f90613a42565b600e54156119c357600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd916004808301926020929190829003018186803b15801561196657600080fd5b505afa15801561197a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199e91906136b1565b9050600e5481116119c15760405162461bcd60e51b815260040161056f90613ea4565b505b60085460ff166119e55760405162461bcd60e51b815260040161056f90613d80565b336000908152600b602052604090206119ff816009611e6a565b8215611a2657600254611a1d906001600160a01b0316333086612838565b611a26836122b1565b600354600254600091611a46916001600160a01b03918216911685610f5b565b90508015611b195760035460405163079cc67960e41b81526001600160a01b03909116906379cc679090611a809033908790600401613846565b600060405180830381600087803b158015611a9a57600080fd5b505af1158015611aae573d6000803e3d6000fd5b505060035460405163288aafcb60e01b81526001600160a01b03909116925063288aafcb9150611ae29086906004016138af565b600060405180830381600087803b158015611afc57600080fd5b505af1158015611b10573d6000803e3d6000fd5b50505050611b1e565b600092505b6000611b2a8583612813565b6001840154909150611b3c90826123b8565b60018401556040518490869033907fbade234341a40ca3c71df59b3ca02b8bb65b491a098af970953228b4f4a5d38f90600090a450506001600055505050565b6002546000906001600160a01b03848116911614611bac5760405162461bcd60e51b815260040161056f9061394b565b611bb5826125de565b90505b92915050565b600854600090819060ff16611be55760405162461bcd60e51b815260040161056f90613d80565b6000611bf2600c85611e06565b9050600080611c018330612d59565b91509150611c0e82612921565b604051819083907f11d2034f4471d11a13f0f1798ceaf0c9db2812d450a0681958ce7d4f2fb97f0990600090a3909350915050915091565b6001546001600160a01b03163314611c705760405162461bcd60e51b815260040161056f90613bc3565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611cbe57600080fd5b505afa158015611cd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf691906135f2565b6001600160a01b0316816001600160a01b03161415611d275760405162461bcd60e51b815260040161056f90613daa565b600580546001600160a01b0319166001600160a01b0383169081179091556040517f05f3326e0527f309d4015dee3bc3f36e650b53fc823bab69c99847814acfafdf90600090a250565b60075481565b6001600160a01b0381166000908152600b602052604081206112a0816009612dac565b6002546001600160a01b031681565b60008060026000541415611dcf5760405162461bcd60e51b815260040161056f90613e6d565b600260005560085460ff16611df65760405162461bcd60e51b815260040161056f90613d80565b610c1c8484612522565b60065481565b6000826000018281548110611e1757fe5b9060005260206000209060020201905092915050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611e6257600080fd5b565b3b151590565b6000611e768383612dfb565b90508260010154811115611ea4576001830180546000909155611e9982826123b8565b600285015550611ec0565b600060028401556001830154611eba90826123b8565b60018401555b5060010154600490910155565b6002546040516370a0823160e01b815260009182918291611f5d9186916001600160a01b0316906370a0823190611f089030906004016137d9565b60206040518083038186803b158015611f2057600080fd5b505afa158015611f34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5891906136b1565b612e6b565b90506001600160a01b0385163014611f8657600254611f86906001600160a01b03168683612725565b80806000611f9487836123b8565b90508015611fd9576000611fa8600c612e81565b9050600080611fb8838c86612eac565b9092509050611fc78683612813565b9550611fd38582612813565b94505050505b600654611fe690836123b8565b600655509093509150505b9250929050565b6000818484111561201c5760405162461bcd60e51b815260040161056f91906138b8565b505050900390565b61202e8383612ee2565b819061204d5760405162461bcd60e51b815260040161056f91906138b8565b50505050565b600080612060600c612e81565b6002546040516370a0823160e01b81529192506000916001600160a01b03909116906370a08231906120969030906004016137d9565b60206040518083038186803b1580156120ae57600080fd5b505afa1580156120c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e691906136b1565b600f546040516360ccef1960e11b81529192506000916001600160a01b039091169063c199de3290612135907546525945525f5641554c545f50455243454e5441474560501b906004016138af565b60206040518083038186803b15801561214d57600080fd5b505afa158015612161573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061218591906136b1565b90506000612239600f60009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b1580156121da57600080fd5b505afa1580156121ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221291906136b1565b6122338461222d88600101548861281390919063ffffffff16565b90612b10565b90612ade565b905083600101548111156122a457600061226a6122638660010154846123b890919063ffffffff16565b8690612f0a565b60405190915081907f860f4701faa0ecdeecd9e9eaae11a8612bbd01c663081f7c0c4e4873df653d6990600090a29450610baf9350505050565b6000945050505050610baf565b6004546002546122ce916001600160a01b03918216911683612fb1565b60048054604051631f72642160e31b81526001600160a01b039091169163fb932108916122ff913091869101613846565b600060405180830381600087803b15801561231957600080fd5b505af115801561232d573d6000803e3d6000fd5b50506002546003546000935061235192506001600160a01b03918216911684610f5b565b60035460405163288aafcb60e01b81529192506001600160a01b03169063288aafcb906123829084906004016138af565b600060405180830381600087803b15801561239c57600080fd5b505af11580156123b0573d6000803e3d6000fd5b505050505050565b6000828211156123da5760405162461bcd60e51b815260040161056f90613af1565b50900390565b6123e86135c3565b604051806020016040528061251a8460000160009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b15801561244657600080fd5b505afa15801561245a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247e91906136b1565b85546040516360ccef1960e11b8152612233916001600160a01b03169063c199de32906124bb906823292ca2a92fa62a2b60b91b906004016138af565b60206040518083038186803b1580156124d357600080fd5b505afa1580156124e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250b91906136b1565b673782dace9d90000090612b10565b905292915050565b6008546000908190610100900460ff168061254757506001546001600160a01b031633145b8061255b5750612557600c613098565b8414155b6125775760405162461bcd60e51b815260040161056f90613c4e565b6000612584600c86611e06565b9050600080612594833088612eac565b91509150867fccbd929f935422b28ee209a0db0556280b0a3d9bc4da58f1d3f0ab4f8a49964783836040516125ca929190613f03565b60405180910390a290969095509350505050565b600f546040516360ccef1960e11b815260009182916001600160a01b039091169063c199de3290612633907f46525945525f464c4153485f4645455f50524f504f5254494f4e000000000000906004016138af565b60206040518083038186803b15801561264b57600080fd5b505afa15801561265f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268391906136b1565b90506000600f60009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d557600080fd5b505afa1580156126e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270d91906136b1565b905061271d816122338685612b10565b949350505050565b60006060846001600160a01b031663a9059cbb858560405160240161274b929190613846565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161278491906137bd565b6000604051808303816000865af19150503d80600081146127c1576040519150601f19603f3d011682016040523d82523d6000602084013e6127c6565b606091505b50915091508180156127f05750805115806127f05750808060200190518101906127f09190613695565b61280c5760405162461bcd60e51b815260040161056f906138eb565b5050505050565b600082820183811015611bb55760405162461bcd60e51b815260040161056f9061398c565b60006060856001600160a01b03166323b872dd8686866040516024016128609392919061385f565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161289991906137bd565b6000604051808303816000865af19150503d80600081146128d6576040519150601f19603f3d011682016040523d82523d6000602084013e6128db565b606091505b50915091508180156129055750805115806129055750808060200190518101906129059190613695565b6123b05760405162461bcd60e51b815260040161056f90613e29565b80156118b557600f546040516360ccef1960e11b81526000916001600160a01b03169063c199de329061296c907046525945525f484152564553545f46454560781b906004016138af565b60206040518083038186803b15801561298457600080fd5b505afa158015612998573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bc91906136b1565b90506000612a53600f60009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1157600080fd5b505afa158015612a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4991906136b1565b6122338585612b10565b90506000612a6184836123b8565b60065490915015612aac57612a746135c3565b612a89600654612a83846130e5565b90613127565b6040805160208101909152600a548152909150612aa6908261315b565b51600a55505b8115612acf57600554600254612acf916001600160a01b03918216911684612725565b801561204d5761204d816122b1565b6000808211612aff5760405162461bcd60e51b815260040161056f90613b5f565b818381612b0857fe5b049392505050565b600082612b1f57506000611bb8565b82820282848281612b2c57fe5b0414611bb55760405162461bcd60e51b815260040161056f90613cdf565b5490565b600080612b5b8484612dfb565b905080612b6e5750506001820154611bb8565b6001840154808210612b8557600092505050611bb8565b612b8f81836123b8565b95945050505050565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b158015612be657600080fd5b505afa158015612bfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1e91906135f2565b6001600160a01b0316816001600160a01b03161415612c4f5760405162461bcd60e51b815260040161056f90613aae565b60025460408051637e062a3560e11b8152905183926001600160a01b03908116929084169163fc0c546a91600480820192602092909190829003018186803b158015612c9a57600080fd5b505afa158015612cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd291906135f2565b6001600160a01b031614612cf85760405162461bcd60e51b815260040161056f90613d57565b604080518082019091526001600160a01b038216815260006020820152612d2190600c9061318b565b6040516001600160a01b038316907f0821015de34e20b0878a40f6f165801417f53b2017016d7321cacee989c8cfa790600090a25050565b6000808360010154612d6a85613230565b11612d7a57506000905080611ff1565b6000612d938560010154612d8d87613230565b906123b8565b9050612da08585836132ac565b92509250509250929050565b600080612db98484612dfb565b905080612dcc5750506002820154611bb8565b6001840154808211612de357600092505050611bb8565b612b8f612df083836123b8565b600287015490612813565b6000612e056135c3565b50604080516020810190915260018301548152612e206135c3565b50604080516020810190915260048501548152612e3d8282613466565b612e4c57600092505050611bb8565b8454612b8f90612e6690612e608585613497565b906134b2565b6134e0565b6000818310612e7a5781611bb5565b5090919050565b600081612e8d81613098565b81548110612e9757fe5b90600052602060002090600202019050919050565b6000808080612ebc8787876132ac565b60018901549193509150612ed090826123b8565b60018801559092509050935093915050565b600080612f01612ef285856134ef565b612efb856123e0565b90613466565b13159392505050565b600080612f168461352b565b8454909150612f32906001600160a01b03808416911685612725565b835460405163b6b55f2560e01b81526001600160a01b039091169063b6b55f2590612f619086906004016138af565b600060405180830381600087803b158015612f7b57600080fd5b505af1158015612f8f573d6000803e3d6000fd5b5050506001850154612fa2915084612813565b60018501555081905092915050565b60006060846001600160a01b031663095ea7b38585604051602401612fd7929190613846565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161301091906137bd565b6000604051808303816000865af19150503d806000811461304d576040519150601f19603f3d011682016040523d82523d6000602084013e613052565b606091505b509150915081801561307c57508051158061307c57508080602001905181019061307c9190613695565b61280c5760405162461bcd60e51b815260040161056f90613a0b565b6000806130a483612b4a565b90506112a06001604051806040016040528060118152602001705661756c742e4c6973743a20656d70747960781b81525083611ff89092919063ffffffff16565b6130ed6135c3565b600082158061310a575050670de0b6b3a764000082810290810483145b61311357600080fd5b604080516020810190915290815292915050565b61312f6135c3565b8161313957600080fd5b60405180602001604052808385600001518161315157fe5b0490529392505050565b6131636135c3565b8251825181019081101561317657600080fd5b60408051602081019091529081529392505050565b60005b82548110156131ec578260000181815481106131a657fe5b600091825260209091206002909102015482516001600160a01b03908116911614156131e45760405162461bcd60e51b815260040161056f90613ed0565b60010161318e565b508154600180820184556000938452602093849020835160029093020180546001600160a01b0319166001600160a01b039093169290921782559190920151910155565b8054604080516306a61f7560e51b815290516000926001600160a01b03169163d4c3eea0916004808301926020929190829003018186803b15801561327457600080fd5b505afa158015613288573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb891906136b1565b60008060006132ba8661352b565b90506000816001600160a01b03166370a08231876040518263ffffffff1660e01b81526004016132ea91906137d9565b60206040518083038186803b15801561330257600080fd5b505afa158015613316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061333a91906136b1565b9050600061334788613230565b885460405163f3fef3a360e01b81529192506001600160a01b03169063f3fef3a390613379908a908a90600401613846565b600060405180830381600087803b15801561339357600080fd5b505af11580156133a7573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092506001600160a01b03861691506370a08231906133da908b906004016137d9565b60206040518083038186803b1580156133f257600080fd5b505afa158015613406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342a91906136b1565b9050600061343882856123b8565b905060006134458b613230565b9050600061345385836123b8565b929c929b50919950505050505050505050565b80518251600091111561347c5750600019611bb8565b81518351111561348e57506001611bb8565b50600092915050565b61349f6135c3565b8251825181039081111561317657600080fd5b6134ba6135c3565b60008215806134d75750508251828102908382816134d457fe5b04145b61317657600080fd5b51670de0b6b3a7640000900490565b6134f76135c3565b60006135038484612b4e565b90508061351a576135126135a7565b915050611bb8565b61271d81612a8386600001546130e5565b805460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b15801561356f57600080fd5b505afa158015613583573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb891906135f2565b6135af6135c3565b506040805160208101909152600019815290565b6040518060200160405280600081525090565b6000602082840312156135e7578081fd5b8135611bb581613f3d565b600060208284031215613603578081fd5b8151611bb581613f3d565b600080600060608486031215613622578182fd5b833561362d81613f3d565b9250602084013561363d81613f3d565b929592945050506040919091013590565b60008060408385031215613660578182fd5b823561366b81613f3d565b946020939093013593505050565b60006020828403121561368a578081fd5b8135611bb581613f52565b6000602082840312156136a6578081fd5b8151611bb581613f52565b6000602082840312156136c2578081fd5b5051919050565b6000806000806000608086880312156136e0578081fd5b85356136eb81613f3d565b945060208601356136fb81613f3d565b935060408601359250606086013567ffffffffffffffff8082111561371e578283fd5b818801915088601f830112613731578283fd5b81358181111561373f578384fd5b896020828501011115613750578384fd5b9699959850939650602001949392505050565b600060208284031215613774578081fd5b5035919050565b6000806040838503121561378d578182fd5b50508035926020909101359150565b6000602082840312156137ad578081fd5b815160ff81168114611bb5578182fd5b600082516137cf818460208701613f11565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c084013781830160c090810191909152601f909201601f1916010195945050505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b90815260200190565b60006020825282518060208401526138d7816040850160208701613f11565b601f01601f19169190910160400192915050565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b6020808252600f908201526e494e56414c49445f4144445245535360881b604082015260600190565b60208082526021908201527f466c6173684c656e6465723a20556e737570706f727465642063757272656e636040820152607960f81b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f63616e6e6f7420696e697469616c697a6520726577617264732061646472657360408201526707320746f203078360c41b606082015260800190565b6020808252601e908201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604082015260600190565b6020808252818101527f536f72727920776520646f206e6f742061636365707420636f6e747261637421604082015260600190565b6020808252601d908201527f636f6e66696720616464726573732063616e6e6f74206265203078302e000000604082015260600190565b60208082526023908201527f616374697665207661756c7420616464726573732063616e6e6f7420626520306040820152623c181760e91b606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252601b908201527f6f76656e20616464726573732063616e6e6f74206265203078302e0000000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252600990820152682327a92124a22222a760b91b604082015260600190565b60208082526025908201527f63616e6e6f7420696e697469616c697a65206f76656e2061646472657373207460408201526406f203078360dc1b606082015260800190565b6020808252600990820152684e4f5f4348414e474560b81b604082015260600190565b60208082526065908201527f6e6f7420616e20656d657267656e63792c206e6f7420676f7665726e616e636560408201527f2c20616e64207573657220646f6573206e6f742068617665207065726d69737360608201527f696f6e20746f20726563616c6c2066756e64732066726f6d20616374697665206080820152641d985d5b1d60da1b60a082015260c00190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601c908201527f466c6173684c656e6465723a2043616c6c6261636b206661696c656400000000604082015260600190565b6020808252600f908201526e3a37b5b2b71036b4b9b6b0ba31b41760891b604082015260600190565b60208082526010908201526f3737ba1034b734ba34b0b634bd32b21760811b604082015260600190565b6020808252601e908201527f7265776172647320616464726573732063616e6e6f74206265203078302e0000604082015260600190565b602080825260009082015260400190565b60208082526017908201527f656d657267656e637920706175736520656e61626c6564000000000000000000604082015260600190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416040820152631253115160e21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526012908201527137b333103832b3903634b6b4ba30ba34b7b760711b604082015260600190565b6020808252600f908201526e10a932b832b0ba1030b230b83a32b960891b604082015260600190565b9051815260200190565b918252602082015260400190565b60005b83811015613f2c578181015183820152602001613f14565b8381111561204d5750506000910152565b6001600160a01b03811681146118b557600080fd5b80151581146118b557600080fdfe416374696f6e20626c6f636b65643a20756e6865616c74687920636f6c6c61746572616c697a6174696f6e20726174696fa264697066735822122066f0def471a66fd991c86eb45791a7529df0303974d4379bcd6adf339e00e6fb64736f6c634300060c00330000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000042ef9077d8e79689799673ae588e046f8832cb9500000000000000000000000078001c780563291ed1224c997b6785e28886f642

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102695760003560e01c80639a9af22111610151578063c5ebeaec116100c3578063ec38a86211610087578063ec38a862146104eb578063f0d787a3146104fe578063fc00e8a014610506578063fc0c546a14610519578063fefdc5d114610521578063ff50abdc1461053457610269565b8063c5ebeaec1461048c578063ce5494bb1461049f578063d8aed145146104b2578063d9d98ce4146104c5578063ddc63262146104d857610269565b8063a7c6a10011610115578063a7c6a10014610430578063aa6e043414610438578063aaf166601461044b578063b6b55f251461045e578063bb39ef8214610471578063c4d66de81461047957610269565b80639a9af221146103f25780639d908f5a146104055780639ec5a8941461040d578063a005fda314610415578063a1e401a91461041d57610269565b80634c3a8e02116101ea5780636b9f96ea116101ae5780636b9f96ea146103ac57806375a356cc146103b45780637857a7c6146103c75780637b79b23e146103cf5780638abf6077146103d757806393ce9d23146103df57610269565b80634c3a8e02146103585780635641ec031461036b5780635a9b5e92146103735780635cffe9de14610386578063613255ab1461039957610269565b80632e1a7d4d116102315780632e1a7d4d146102e75780633847f03814610308578063415f12401461031d57806345ee0755146103305780634aaf7c651461034357610269565b8063158ef93e1461026e5780631a2f13631461028c57806320e3dbd4146102a157806322c37b75146102b45780632670fdd8146102c7575b600080fd5b61027661053c565b60405161028391906138a4565b60405180910390f35b61029f61029a3660046135d6565b610545565b005b61029f6102af3660046135d6565b61061e565b61029f6102c2366004613763565b61075d565b6102da6102d5366004613763565b61078c565b60405161028391906137d9565b6102fa6102f5366004613763565b6107ad565b604051610283929190613f03565b610310610955565b60405161028391906138af565b6102fa61032b366004613763565b61095b565b61029f61033e366004613679565b610b2b565b61034b610b9a565b6040516102839190613ef9565b6102fa610366366004613763565b610bb2565b610276610c2c565b61029f61038136600461364e565b610c3a565b6102766103943660046136c9565b610c8a565b6103106103a73660046135d6565b610e2d565b610310610ed5565b6103106103c236600461360e565b610f5b565b6102da61109e565b6103106110ad565b6102da6110d1565b61029f6103ed3660046135d6565b6110e0565b6103106104003660046135d6565b61120b565b6102da611229565b6102da611238565b6102da611247565b61031061042b3660046135d6565b611256565b610310611271565b6103106104463660046135d6565b61127d565b610310610459366004613763565b6112a7565b61029f61046c366004613763565b6112c0565b6102da61140a565b61029f6104873660046135d6565b611419565b61029f61049a366004613763565b6115e7565b61029f6104ad3660046135d6565b611860565b61029f6104c036600461377b565b6118b8565b6103106104d336600461364e565b611b7c565b6102fa6104e6366004613763565b611bbe565b61029f6104f93660046135d6565b611c46565b610310611d71565b6103106105143660046135d6565b611d77565b6102da611d9a565b6102fa61052f36600461377b565b611da9565b610310611e00565b60085460ff1681565b6001546001600160a01b031633146105785760405162461bcd60e51b815260040161056f90613bc3565b60405180910390fd5b6001600160a01b03811661059e5760405162461bcd60e51b815260040161056f90613922565b6001546001600160a01b03828116911614156105cc5760405162461bcd60e51b815260040161056f90613c2b565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907faad46b89531ed10d02d926f4d6bfe234a6126e3fffc02d3b07167575f9c1433790600090a35050565b6001546001600160a01b031633146106485760405162461bcd60e51b815260040161056f90613bc3565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561069657600080fd5b505afa1580156106aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ce91906135f2565b6001600160a01b0316816001600160a01b031614156106ff5760405162461bcd60e51b815260040161056f90613a77565b600f80546001600160a01b038084166001600160a01b031992831681179384905560098054909316939091169290921790556040517f89b8aa6a0bad94aca607eff7d3631d67e0e67b2c775044f517a269ae8b6662af90600090a250565b6001546001600160a01b031633146107875760405162461bcd60e51b815260040161056f90613bc3565b600755565b60008061079a600c84611e06565b546001600160a01b03169150505b919050565b600080600260005414156107d35760405162461bcd60e51b815260040161056f90613e6d565b60026000556107e0611e2d565b6107e933611e64565b1580156107f557503332145b6108115760405162461bcd60e51b815260040161056f90613a42565b60085460ff166108335760405162461bcd60e51b815260040161056f90613d80565b336000908152600b60205260409020600381015443116108655760405162461bcd60e51b815260040161056f90613de1565b610870816009611e6a565b60008061087d3387611ecd565b60408051808201909152601b81527f4578636565647320776974686472617761626c6520616d6f756e740000000000602082015285549294509092506108c591908390611ff8565b8355604080516060810190915260318082526108ee91600991613f616020830139859190612024565b6007548610610901576108ff612053565b505b85336001600160a01b03167fb3ad69dc1d2c6b1f5f5b0927ffd8ee8f1437a156253c8f6dccc75e6f8e4fd38b848460405161093d929190613f03565b60405180910390a36001600055909590945092505050565b600e5481565b600080600260005414156109815760405162461bcd60e51b815260040161056f90613e6d565b600260005561098e611e2d565b61099733611e64565b1580156109a357503332145b6109bf5760405162461bcd60e51b815260040161056f90613a42565b600e5415610a6957600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd916004808301926020929190829003018186803b158015610a0c57600080fd5b505afa158015610a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4491906136b1565b9050600e548111610a675760405162461bcd60e51b815260040161056f90613ea4565b505b60085460ff16610a8b5760405162461bcd60e51b815260040161056f90613d80565b336000908152600b60205260409020610aa5816009611e6a565b8060010154841115610ab957806001015493505b600080610ac63087611ecd565b91509150610ad3826122b1565b8254610adf90826123b8565b83556001830154610af090836123b8565b6001840155604051869033907f3ea051727656be6fd11c2260f244f29ff3c70d1fb077bfa73e89d554e9bb95c79061093d9086908690613f03565b6001546001600160a01b03163314610b555760405162461bcd60e51b815260040161056f90613bc3565b6008805461ff001916610100831515908102919091179091556040517ff0064f2efd0da4bc63eecf2e75590fe8a308eaa526a51c334e50eec09a71104990600090a250565b610ba26135c3565b610bac60096123e0565b90505b90565b60008060026000541415610bd85760405162461bcd60e51b815260040161056f90613e6d565b600260005560085460ff16610bff5760405162461bcd60e51b815260040161056f90613d80565b6000610c0c600c85611e06565b9050610c1c848260010154612522565b6001600055909590945092505050565b600854610100900460ff1681565b6001546001600160a01b03163314610c645760405162461bcd60e51b815260040161056f90613bc3565b600d80546001600160a01b0319166001600160a01b039390931692909217909155600e55565b6002546000906001600160a01b03868116911614610cba5760405162461bcd60e51b815260040161056f9061394b565b6000610cc5856125de565b600254909150610cdf906001600160a01b03168887612725565b6002546040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9916001600160a01b03808b16926323e30c8b92610d3c9233929116908b9088908c908c906004016137ed565b602060405180830381600087803b158015610d5657600080fd5b505af1158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e91906136b1565b14610dab5760405162461bcd60e51b815260040161056f90613d20565b610dce8730610dba8885612813565b6002546001600160a01b0316929190612838565b610dd781612921565b60025460405132917fedc5fb7867c40a2d7e1268a077f82bc782a7302f52cfe37eb01eb0cab9c8ffff91610e18916001600160a01b03169089908690613883565b60405180910390a25060019695505050505050565b6002546000906001600160a01b0383811691161415610ecd576002546040516370a0823160e01b81526001600160a01b03909116906370a0823190610e769030906004016137d9565b60206040518083038186803b158015610e8e57600080fd5b505afa158015610ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec691906136b1565b90506107a8565b5060006107a8565b600060026000541415610efa5760405162461bcd60e51b815260040161056f90613e6d565b600260005560085460ff16610f215760405162461bcd60e51b815260040161056f90613d80565b600854610100900460ff1615610f495760405162461bcd60e51b815260040161056f90613df2565b610f51612053565b9050600160005590565b600080846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9757600080fd5b505afa158015610fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcf919061379c565b60ff1690506000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561100f57600080fd5b505afa158015611023573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611047919061379c565b60ff169050808211156110725761106b61106183836123b8565b8590600a0a612ade565b9250611095565b818111156110915761106b61108782846123b8565b8590600a0a612b10565b8392505b50509392505050565b6003546001600160a01b031681565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b6001546001600160a01b031681565b6001546001600160a01b0316331461110a5760405162461bcd60e51b815260040161056f90613bc3565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561115857600080fd5b505afa15801561116c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119091906135f2565b6001600160a01b0316816001600160a01b031614156111c15760405162461bcd60e51b815260040161056f90613b28565b600480546001600160a01b0319166001600160a01b0383169081179091556040517f88b3009fd17aa3fbf19d233400b10b7282db2bfa2a996dba8bc11c07b98d521090600090a250565b6001600160a01b03166000908152600b602052604090206003015490565b6004546001600160a01b031681565b6005546001600160a01b031681565b600d546001600160a01b031681565b6001600160a01b03166000908152600b602052604090205490565b6000610bac600c612b4a565b6001600160a01b0381166000908152600b602052604081206112a0816009612b4e565b9392505050565b6000806112b5600c84611e06565b600101549392505050565b600260005414156112e35760405162461bcd60e51b815260040161056f90613e6d565b60026000556112f0611e2d565b6112f933611e64565b15801561130557503332145b6113215760405162461bcd60e51b815260040161056f90613a42565b60085460ff166113435760405162461bcd60e51b815260040161056f90613d80565b600854610100900460ff161561136b5760405162461bcd60e51b815260040161056f90613df2565b336000908152600b60205260409020611385816009611e6a565b60025461139d906001600160a01b0316333085612838565b6006546113aa9083612813565b60065580546113b99083612813565b815543600382015560075482106113d4576113d2612053565b505b604051829033907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e90600090a350506001600055565b600f546001600160a01b031681565b6001546001600160a01b031633146114435760405162461bcd60e51b815260040161056f90613bc3565b60085460ff16156114665760405162461bcd60e51b815260040161056f90613b96565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b457600080fd5b505afa1580156114c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ec91906135f2565b6004546001600160a01b039081169116141561151a5760405162461bcd60e51b815260040161056f90613be6565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561156857600080fd5b505afa15801561157c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a091906135f2565b6005546001600160a01b03908116911614156115ce5760405162461bcd60e51b815260040161056f906139c3565b6115d781612b98565b506008805460ff19166001179055565b6002600054141561160a5760405162461bcd60e51b815260040161056f90613e6d565b6002600055611617611e2d565b61162033611e64565b15801561162c57503332145b6116485760405162461bcd60e51b815260040161056f90613a42565b600e54156116f257600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd916004808301926020929190829003018186803b15801561169557600080fd5b505afa1580156116a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cd91906136b1565b9050600e5481116116f05760405162461bcd60e51b815260040161056f90613ea4565b505b60085460ff166117145760405162461bcd60e51b815260040161056f90613d80565b336000908152600b6020526040902061172e816009611e6a565b6002810154828110156117ad57600061174784836123b8565b60018401549091506117599082612813565b60018401556000600284015560408051808201909152601c81527f4c6f616e2d746f2d76616c756520726174696f2062726561636865640000000060208201526117a7908490600990612024565b506117bd565b6117b781846123b8565b60028301555b6002546003546000916117dd916001600160a01b03918216911686610f5b565b6003546040516340c10f1960e01b81529192506001600160a01b0316906340c10f19906118109033908590600401613846565b600060405180830381600087803b15801561182a57600080fd5b505af115801561183e573d6000803e3d6000fd5b50505050600754841061185557611853612053565b505b505060016000555050565b60085460ff166118825760405162461bcd60e51b815260040161056f90613d80565b6001546001600160a01b031633146118ac5760405162461bcd60e51b815260040161056f90613bc3565b6118b581612b98565b50565b600260005414156118db5760405162461bcd60e51b815260040161056f90613e6d565b60026000556118e8611e2d565b6118f133611e64565b1580156118fd57503332145b6119195760405162461bcd60e51b815260040161056f90613a42565b600e54156119c357600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd916004808301926020929190829003018186803b15801561196657600080fd5b505afa15801561197a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199e91906136b1565b9050600e5481116119c15760405162461bcd60e51b815260040161056f90613ea4565b505b60085460ff166119e55760405162461bcd60e51b815260040161056f90613d80565b336000908152600b602052604090206119ff816009611e6a565b8215611a2657600254611a1d906001600160a01b0316333086612838565b611a26836122b1565b600354600254600091611a46916001600160a01b03918216911685610f5b565b90508015611b195760035460405163079cc67960e41b81526001600160a01b03909116906379cc679090611a809033908790600401613846565b600060405180830381600087803b158015611a9a57600080fd5b505af1158015611aae573d6000803e3d6000fd5b505060035460405163288aafcb60e01b81526001600160a01b03909116925063288aafcb9150611ae29086906004016138af565b600060405180830381600087803b158015611afc57600080fd5b505af1158015611b10573d6000803e3d6000fd5b50505050611b1e565b600092505b6000611b2a8583612813565b6001840154909150611b3c90826123b8565b60018401556040518490869033907fbade234341a40ca3c71df59b3ca02b8bb65b491a098af970953228b4f4a5d38f90600090a450506001600055505050565b6002546000906001600160a01b03848116911614611bac5760405162461bcd60e51b815260040161056f9061394b565b611bb5826125de565b90505b92915050565b600854600090819060ff16611be55760405162461bcd60e51b815260040161056f90613d80565b6000611bf2600c85611e06565b9050600080611c018330612d59565b91509150611c0e82612921565b604051819083907f11d2034f4471d11a13f0f1798ceaf0c9db2812d450a0681958ce7d4f2fb97f0990600090a3909350915050915091565b6001546001600160a01b03163314611c705760405162461bcd60e51b815260040161056f90613bc3565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611cbe57600080fd5b505afa158015611cd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf691906135f2565b6001600160a01b0316816001600160a01b03161415611d275760405162461bcd60e51b815260040161056f90613daa565b600580546001600160a01b0319166001600160a01b0383169081179091556040517f05f3326e0527f309d4015dee3bc3f36e650b53fc823bab69c99847814acfafdf90600090a250565b60075481565b6001600160a01b0381166000908152600b602052604081206112a0816009612dac565b6002546001600160a01b031681565b60008060026000541415611dcf5760405162461bcd60e51b815260040161056f90613e6d565b600260005560085460ff16611df65760405162461bcd60e51b815260040161056f90613d80565b610c1c8484612522565b60065481565b6000826000018281548110611e1757fe5b9060005260206000209060020201905092915050565b306001600160a01b037f00000000000000000000000087f6faa87358b628498e8dcd4e30b0378feafd071614611e6257600080fd5b565b3b151590565b6000611e768383612dfb565b90508260010154811115611ea4576001830180546000909155611e9982826123b8565b600285015550611ec0565b600060028401556001830154611eba90826123b8565b60018401555b5060010154600490910155565b6002546040516370a0823160e01b815260009182918291611f5d9186916001600160a01b0316906370a0823190611f089030906004016137d9565b60206040518083038186803b158015611f2057600080fd5b505afa158015611f34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5891906136b1565b612e6b565b90506001600160a01b0385163014611f8657600254611f86906001600160a01b03168683612725565b80806000611f9487836123b8565b90508015611fd9576000611fa8600c612e81565b9050600080611fb8838c86612eac565b9092509050611fc78683612813565b9550611fd38582612813565b94505050505b600654611fe690836123b8565b600655509093509150505b9250929050565b6000818484111561201c5760405162461bcd60e51b815260040161056f91906138b8565b505050900390565b61202e8383612ee2565b819061204d5760405162461bcd60e51b815260040161056f91906138b8565b50505050565b600080612060600c612e81565b6002546040516370a0823160e01b81529192506000916001600160a01b03909116906370a08231906120969030906004016137d9565b60206040518083038186803b1580156120ae57600080fd5b505afa1580156120c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e691906136b1565b600f546040516360ccef1960e11b81529192506000916001600160a01b039091169063c199de3290612135907546525945525f5641554c545f50455243454e5441474560501b906004016138af565b60206040518083038186803b15801561214d57600080fd5b505afa158015612161573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061218591906136b1565b90506000612239600f60009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b1580156121da57600080fd5b505afa1580156121ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221291906136b1565b6122338461222d88600101548861281390919063ffffffff16565b90612b10565b90612ade565b905083600101548111156122a457600061226a6122638660010154846123b890919063ffffffff16565b8690612f0a565b60405190915081907f860f4701faa0ecdeecd9e9eaae11a8612bbd01c663081f7c0c4e4873df653d6990600090a29450610baf9350505050565b6000945050505050610baf565b6004546002546122ce916001600160a01b03918216911683612fb1565b60048054604051631f72642160e31b81526001600160a01b039091169163fb932108916122ff913091869101613846565b600060405180830381600087803b15801561231957600080fd5b505af115801561232d573d6000803e3d6000fd5b50506002546003546000935061235192506001600160a01b03918216911684610f5b565b60035460405163288aafcb60e01b81529192506001600160a01b03169063288aafcb906123829084906004016138af565b600060405180830381600087803b15801561239c57600080fd5b505af11580156123b0573d6000803e3d6000fd5b505050505050565b6000828211156123da5760405162461bcd60e51b815260040161056f90613af1565b50900390565b6123e86135c3565b604051806020016040528061251a8460000160009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b15801561244657600080fd5b505afa15801561245a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247e91906136b1565b85546040516360ccef1960e11b8152612233916001600160a01b03169063c199de32906124bb906823292ca2a92fa62a2b60b91b906004016138af565b60206040518083038186803b1580156124d357600080fd5b505afa1580156124e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250b91906136b1565b673782dace9d90000090612b10565b905292915050565b6008546000908190610100900460ff168061254757506001546001600160a01b031633145b8061255b5750612557600c613098565b8414155b6125775760405162461bcd60e51b815260040161056f90613c4e565b6000612584600c86611e06565b9050600080612594833088612eac565b91509150867fccbd929f935422b28ee209a0db0556280b0a3d9bc4da58f1d3f0ab4f8a49964783836040516125ca929190613f03565b60405180910390a290969095509350505050565b600f546040516360ccef1960e11b815260009182916001600160a01b039091169063c199de3290612633907f46525945525f464c4153485f4645455f50524f504f5254494f4e000000000000906004016138af565b60206040518083038186803b15801561264b57600080fd5b505afa15801561265f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268391906136b1565b90506000600f60009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d557600080fd5b505afa1580156126e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270d91906136b1565b905061271d816122338685612b10565b949350505050565b60006060846001600160a01b031663a9059cbb858560405160240161274b929190613846565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161278491906137bd565b6000604051808303816000865af19150503d80600081146127c1576040519150601f19603f3d011682016040523d82523d6000602084013e6127c6565b606091505b50915091508180156127f05750805115806127f05750808060200190518101906127f09190613695565b61280c5760405162461bcd60e51b815260040161056f906138eb565b5050505050565b600082820183811015611bb55760405162461bcd60e51b815260040161056f9061398c565b60006060856001600160a01b03166323b872dd8686866040516024016128609392919061385f565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161289991906137bd565b6000604051808303816000865af19150503d80600081146128d6576040519150601f19603f3d011682016040523d82523d6000602084013e6128db565b606091505b50915091508180156129055750805115806129055750808060200190518101906129059190613695565b6123b05760405162461bcd60e51b815260040161056f90613e29565b80156118b557600f546040516360ccef1960e11b81526000916001600160a01b03169063c199de329061296c907046525945525f484152564553545f46454560781b906004016138af565b60206040518083038186803b15801561298457600080fd5b505afa158015612998573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bc91906136b1565b90506000612a53600f60009054906101000a90046001600160a01b03166001600160a01b0316639e6c29596040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1157600080fd5b505afa158015612a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4991906136b1565b6122338585612b10565b90506000612a6184836123b8565b60065490915015612aac57612a746135c3565b612a89600654612a83846130e5565b90613127565b6040805160208101909152600a548152909150612aa6908261315b565b51600a55505b8115612acf57600554600254612acf916001600160a01b03918216911684612725565b801561204d5761204d816122b1565b6000808211612aff5760405162461bcd60e51b815260040161056f90613b5f565b818381612b0857fe5b049392505050565b600082612b1f57506000611bb8565b82820282848281612b2c57fe5b0414611bb55760405162461bcd60e51b815260040161056f90613cdf565b5490565b600080612b5b8484612dfb565b905080612b6e5750506001820154611bb8565b6001840154808210612b8557600092505050611bb8565b612b8f81836123b8565b95945050505050565b600f60009054906101000a90046001600160a01b03166001600160a01b031663538ba4f96040518163ffffffff1660e01b815260040160206040518083038186803b158015612be657600080fd5b505afa158015612bfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1e91906135f2565b6001600160a01b0316816001600160a01b03161415612c4f5760405162461bcd60e51b815260040161056f90613aae565b60025460408051637e062a3560e11b8152905183926001600160a01b03908116929084169163fc0c546a91600480820192602092909190829003018186803b158015612c9a57600080fd5b505afa158015612cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd291906135f2565b6001600160a01b031614612cf85760405162461bcd60e51b815260040161056f90613d57565b604080518082019091526001600160a01b038216815260006020820152612d2190600c9061318b565b6040516001600160a01b038316907f0821015de34e20b0878a40f6f165801417f53b2017016d7321cacee989c8cfa790600090a25050565b6000808360010154612d6a85613230565b11612d7a57506000905080611ff1565b6000612d938560010154612d8d87613230565b906123b8565b9050612da08585836132ac565b92509250509250929050565b600080612db98484612dfb565b905080612dcc5750506002820154611bb8565b6001840154808211612de357600092505050611bb8565b612b8f612df083836123b8565b600287015490612813565b6000612e056135c3565b50604080516020810190915260018301548152612e206135c3565b50604080516020810190915260048501548152612e3d8282613466565b612e4c57600092505050611bb8565b8454612b8f90612e6690612e608585613497565b906134b2565b6134e0565b6000818310612e7a5781611bb5565b5090919050565b600081612e8d81613098565b81548110612e9757fe5b90600052602060002090600202019050919050565b6000808080612ebc8787876132ac565b60018901549193509150612ed090826123b8565b60018801559092509050935093915050565b600080612f01612ef285856134ef565b612efb856123e0565b90613466565b13159392505050565b600080612f168461352b565b8454909150612f32906001600160a01b03808416911685612725565b835460405163b6b55f2560e01b81526001600160a01b039091169063b6b55f2590612f619086906004016138af565b600060405180830381600087803b158015612f7b57600080fd5b505af1158015612f8f573d6000803e3d6000fd5b5050506001850154612fa2915084612813565b60018501555081905092915050565b60006060846001600160a01b031663095ea7b38585604051602401612fd7929190613846565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161301091906137bd565b6000604051808303816000865af19150503d806000811461304d576040519150601f19603f3d011682016040523d82523d6000602084013e613052565b606091505b509150915081801561307c57508051158061307c57508080602001905181019061307c9190613695565b61280c5760405162461bcd60e51b815260040161056f90613a0b565b6000806130a483612b4a565b90506112a06001604051806040016040528060118152602001705661756c742e4c6973743a20656d70747960781b81525083611ff89092919063ffffffff16565b6130ed6135c3565b600082158061310a575050670de0b6b3a764000082810290810483145b61311357600080fd5b604080516020810190915290815292915050565b61312f6135c3565b8161313957600080fd5b60405180602001604052808385600001518161315157fe5b0490529392505050565b6131636135c3565b8251825181019081101561317657600080fd5b60408051602081019091529081529392505050565b60005b82548110156131ec578260000181815481106131a657fe5b600091825260209091206002909102015482516001600160a01b03908116911614156131e45760405162461bcd60e51b815260040161056f90613ed0565b60010161318e565b508154600180820184556000938452602093849020835160029093020180546001600160a01b0319166001600160a01b039093169290921782559190920151910155565b8054604080516306a61f7560e51b815290516000926001600160a01b03169163d4c3eea0916004808301926020929190829003018186803b15801561327457600080fd5b505afa158015613288573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb891906136b1565b60008060006132ba8661352b565b90506000816001600160a01b03166370a08231876040518263ffffffff1660e01b81526004016132ea91906137d9565b60206040518083038186803b15801561330257600080fd5b505afa158015613316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061333a91906136b1565b9050600061334788613230565b885460405163f3fef3a360e01b81529192506001600160a01b03169063f3fef3a390613379908a908a90600401613846565b600060405180830381600087803b15801561339357600080fd5b505af11580156133a7573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092506001600160a01b03861691506370a08231906133da908b906004016137d9565b60206040518083038186803b1580156133f257600080fd5b505afa158015613406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342a91906136b1565b9050600061343882856123b8565b905060006134458b613230565b9050600061345385836123b8565b929c929b50919950505050505050505050565b80518251600091111561347c5750600019611bb8565b81518351111561348e57506001611bb8565b50600092915050565b61349f6135c3565b8251825181039081111561317657600080fd5b6134ba6135c3565b60008215806134d75750508251828102908382816134d457fe5b04145b61317657600080fd5b51670de0b6b3a7640000900490565b6134f76135c3565b60006135038484612b4e565b90508061351a576135126135a7565b915050611bb8565b61271d81612a8386600001546130e5565b805460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b15801561356f57600080fd5b505afa158015613583573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb891906135f2565b6135af6135c3565b506040805160208101909152600019815290565b6040518060200160405280600081525090565b6000602082840312156135e7578081fd5b8135611bb581613f3d565b600060208284031215613603578081fd5b8151611bb581613f3d565b600080600060608486031215613622578182fd5b833561362d81613f3d565b9250602084013561363d81613f3d565b929592945050506040919091013590565b60008060408385031215613660578182fd5b823561366b81613f3d565b946020939093013593505050565b60006020828403121561368a578081fd5b8135611bb581613f52565b6000602082840312156136a6578081fd5b8151611bb581613f52565b6000602082840312156136c2578081fd5b5051919050565b6000806000806000608086880312156136e0578081fd5b85356136eb81613f3d565b945060208601356136fb81613f3d565b935060408601359250606086013567ffffffffffffffff8082111561371e578283fd5b818801915088601f830112613731578283fd5b81358181111561373f578384fd5b896020828501011115613750578384fd5b9699959850939650602001949392505050565b600060208284031215613774578081fd5b5035919050565b6000806040838503121561378d578182fd5b50508035926020909101359150565b6000602082840312156137ad578081fd5b815160ff81168114611bb5578182fd5b600082516137cf818460208701613f11565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c084013781830160c090810191909152601f909201601f1916010195945050505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b90815260200190565b60006020825282518060208401526138d7816040850160208701613f11565b601f01601f19169190910160400192915050565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b6020808252600f908201526e494e56414c49445f4144445245535360881b604082015260600190565b60208082526021908201527f466c6173684c656e6465723a20556e737570706f727465642063757272656e636040820152607960f81b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f63616e6e6f7420696e697469616c697a6520726577617264732061646472657360408201526707320746f203078360c41b606082015260800190565b6020808252601e908201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604082015260600190565b6020808252818101527f536f72727920776520646f206e6f742061636365707420636f6e747261637421604082015260600190565b6020808252601d908201527f636f6e66696720616464726573732063616e6e6f74206265203078302e000000604082015260600190565b60208082526023908201527f616374697665207661756c7420616464726573732063616e6e6f7420626520306040820152623c181760e91b606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252601b908201527f6f76656e20616464726573732063616e6e6f74206265203078302e0000000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252600990820152682327a92124a22222a760b91b604082015260600190565b60208082526025908201527f63616e6e6f7420696e697469616c697a65206f76656e2061646472657373207460408201526406f203078360dc1b606082015260800190565b6020808252600990820152684e4f5f4348414e474560b81b604082015260600190565b60208082526065908201527f6e6f7420616e20656d657267656e63792c206e6f7420676f7665726e616e636560408201527f2c20616e64207573657220646f6573206e6f742068617665207065726d69737360608201527f696f6e20746f20726563616c6c2066756e64732066726f6d20616374697665206080820152641d985d5b1d60da1b60a082015260c00190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601c908201527f466c6173684c656e6465723a2043616c6c6261636b206661696c656400000000604082015260600190565b6020808252600f908201526e3a37b5b2b71036b4b9b6b0ba31b41760891b604082015260600190565b60208082526010908201526f3737ba1034b734ba34b0b634bd32b21760811b604082015260600190565b6020808252601e908201527f7265776172647320616464726573732063616e6e6f74206265203078302e0000604082015260600190565b602080825260009082015260400190565b60208082526017908201527f656d657267656e637920706175736520656e61626c6564000000000000000000604082015260600190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416040820152631253115160e21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526012908201527137b333103832b3903634b6b4ba30ba34b7b760711b604082015260600190565b6020808252600f908201526e10a932b832b0ba1030b230b83a32b960891b604082015260600190565b9051815260200190565b918252602082015260400190565b60005b83811015613f2c578181015183820152602001613f14565b8381111561204d5750506000910152565b6001600160a01b03811681146118b557600080fd5b80151581146118b557600080fdfe416374696f6e20626c6f636b65643a20756e6865616c74687920636f6c6c61746572616c697a6174696f6e20726174696fa264697066735822122066f0def471a66fd991c86eb45791a7529df0303974d4379bcd6adf339e00e6fb64736f6c634300060c0033

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

0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000042ef9077d8e79689799673ae588e046f8832cb9500000000000000000000000078001c780563291ed1224c997b6785e28886f642

-----Decoded View---------------
Arg [0] : _token (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [1] : _friesToken (address): 0x42ef9077d8e79689799673ae588E046f8832CB95
Arg [2] : _fryerConfig (address): 0x78001C780563291ED1224c997b6785e28886F642

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [1] : 00000000000000000000000042ef9077d8e79689799673ae588e046f8832cb95
Arg [2] : 00000000000000000000000078001c780563291ed1224c997b6785e28886f642


Deployed Bytecode Sourcemap

55348:18749:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57349:23;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26780:283;;;;;;:::i;:::-;;:::i;:::-;;58432:317;;;;;;:::i;:::-;;:::i;58757:124::-;;;;;;:::i;:::-;;:::i;68387:213::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64380:1013::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;57572:25::-;;;:::i;:::-;;;;;;;:::i;66458:906::-;;;;;;:::i;:::-;;:::i;59338:171::-;;;;;;:::i;:::-;;:::i;59517:179::-;;;:::i;:::-;;;;;;;:::i;62405:276::-;;;;;;:::i;:::-;;:::i;57381:25::-;;;:::i;59162:168::-;;;;;;:::i;:::-;;:::i;72254:805::-;;;;;;:::i;:::-;;:::i;73822:272::-;;;;;;:::i;:::-;;:::i;62689:182::-;;;:::i;53563:550::-;;;;;;:::i;:::-;;:::i;57180:25::-;;;:::i;56998:103::-;;;:::i;26507:19::-;;;:::i;58183:241::-;;;;;;:::i;:::-;;:::i;69466:201::-;;;;;;:::i;:::-;;:::i;57214:19::-;;;:::i;57242:22::-;;;:::i;57534:29::-;;;:::i;68837:207::-;;;;;;:::i;:::-;;:::i;68283:96::-;;;:::i;69052:181::-;;;;;;:::i;:::-;;:::i;68608:221::-;;;;;;:::i;:::-;;:::i;63685:687::-;;;;;;:::i;:::-;;:::i;57606:31::-;;;:::i;59704:460::-;;;;;;:::i;:::-;;:::i;67372:903::-;;;;;;:::i;:::-;;:::i;60172:121::-;;;;;;:::i;:::-;;:::i;65401:1049::-;;;;;;:::i;:::-;;:::i;73067:247::-;;;;;;:::i;:::-;;:::i;60745:470::-;;;;;;:::i;:::-;;:::i;58889:265::-;;;;;;:::i;:::-;;:::i;57311:29::-;;;:::i;69241:217::-;;;;;;:::i;:::-;;:::i;57132:20::-;;;:::i;62181:216::-;;;;;;:::i;:::-;;:::i;57273:29::-;;;:::i;57349:23::-;;;;;;:::o;26780:283::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;26857:22:0;::::1;26849:50;;;;-1:-1:-1::0;;;26849:50:0::1;;;;;;;:::i;:::-;26930:4;::::0;-1:-1:-1;;;;;26918:16:0;;::::1;26930:4:::0;::::1;26918:16;;26910:38;;;;-1:-1:-1::0;;;26910:38:0::1;;;;;;;:::i;:::-;26978:4;::::0;;-1:-1:-1;;;;;26993:15:0;;::::1;-1:-1:-1::0;;;;;;26993:15:0;::::1;::::0;::::1;::::0;;;27024:31:::1;::::0;26978:4;::::1;::::0;26993:15;26978:4;;27024:31:::1;::::0;26959:16:::1;::::0;27024:31:::1;26763:1;26780:283:::0;:::o;58432:317::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;58533:11:::1;;;;;;;;;-1:-1:-1::0;;;;;58533:11:0::1;-1:-1:-1::0;;;;;58533:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58522:37:0::1;:7;-1:-1:-1::0;;;;;58522:37:0::1;;;58500:116;;;;-1:-1:-1::0;;;58500:116:0::1;;;;;;;:::i;:::-;58627:11;:35:::0;;-1:-1:-1;;;;;58627:35:0;;::::1;-1:-1:-1::0;;;;;;58627:35:0;;::::1;::::0;::::1;::::0;;;;58673:4:::1;:30:::0;;;;::::1;58692:11:::0;;;::::1;58673:30:::0;;;::::1;::::0;;58719:22:::1;::::0;::::1;::::0;58627:11:::1;::::0;58719:22:::1;58432:317:::0;:::o;58757:124::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;58841:14:::1;:32:::0;58757:124::o;68387:213::-;68480:13;;68539:21;:7;68551:8;68539:11;:21::i;:::-;68578:14;-1:-1:-1;;;;;68578:14:0;;-1:-1:-1;;68387:213:0;;;;:::o;64380:1013::-;64551:7;64560;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;55225:22:::1;:20;:22::i;:::-;70314:32:::2;70322:10;70314:30;:32::i;:::-;70313:33;:60;;;;-1:-1:-1::0;70350:10:0::2;70364:9;70350:23;70313:60;70291:142;;;;-1:-1:-1::0;;;70291:142:0::2;;;;;;;:::i;:::-;58123:11:::3;::::0;::::3;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::3;;;;;;;:::i;:::-;64615:10:::4;64585:21;64609:17:::0;;;:5:::4;:17;::::0;;;;64660:16:::4;::::0;::::4;::::0;64645:12:::4;:31;64637:44;;;;-1:-1:-1::0;;;64637:44:0::4;;;;;;;:::i;:::-;64694:17;:4:::0;64706::::4;64694:11;:17::i;:::-;64725:24;64751:23:::0;64791:37:::4;64808:10;64820:7;64791:16;:37::i;:::-;64863:108;::::0;;;;::::4;::::0;;;::::4;::::0;;::::4;;::::0;::::4;::::0;:19;;64724:104;;-1:-1:-1;64724:104:0;;-1:-1:-1;64863:108:0::4;::::0;:19;64724:104;;64863:23:::4;:108::i;:::-;64841:130:::0;;64982:112:::4;::::0;;::::4;::::0;::::4;::::0;;;::::4;::::0;;;::::4;::::0;65013:4:::4;::::0;64982:112:::4;;::::0;::::4;;:4:::0;;:112;:16:::4;:112::i;:::-;65120:14;;65109:7;:25;65105:76;;65151:18;:16;:18::i;:::-;;65105:76;65251:7;65226:10;-1:-1:-1::0;;;;;65196:134:0::4;;65273:16;65304:15;65196:134;;;;;;;:::i;:::-;;;;;;;;2628:1:::0;3590:7;:22;65351:16;;;;-1:-1:-1;64380:1013:0;-1:-1:-1;;;64380:1013:0:o;57572:25::-;;;;:::o;66458:906::-;66651:7;66660;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;55225:22:::1;:20;:22::i;:::-;70314:32:::2;70322:10;70314:30;:32::i;:::-;70313:33;:60;;;;-1:-1:-1::0;70350:10:0::2;70364:9;70350:23;70313:60;70291:142;;;;-1:-1:-1::0;;;70291:142:0::2;;;;;;;:::i;:::-;70020:10:::3;::::0;:14;70016:208:::3;;70110:14;::::0;70099:41:::3;::::0;;-1:-1:-1;;;70099:41:0;;;;70051:20:::3;::::0;-1:-1:-1;;;;;70110:14:0::3;::::0;70099:39:::3;::::0;:41:::3;::::0;;::::3;::::0;::::3;::::0;;;;;;;;70110:14;70099:41;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70051:90;;70179:10;;70164:12;:25;70156:56;;;;-1:-1:-1::0;;;70156:56:0::3;;;;;;;:::i;:::-;70016:208;;58123:11:::4;::::0;::::4;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::4;;;;;;;:::i;:::-;66715:10:::5;66685:21;66709:17:::0;;;:5:::5;:17;::::0;;;;66737::::5;66709::::0;66749:4:::5;66737:11;:17::i;:::-;66781:4;:14;;;66771:7;:24;66767:81;;;66822:4;:14;;;66812:24;;66767:81;66859:24;66885:23:::0;66925:40:::5;66950:4;66957:7;66925:16;:40::i;:::-;66858:107;;;;66976:35;66994:16;66976:17;:35::i;:::-;67046:19:::0;;:40:::5;::::0;67070:15;67046:23:::5;:40::i;:::-;67024:62:::0;;67114:14:::5;::::0;::::5;::::0;:36:::5;::::0;67133:16;67114:18:::5;:36::i;:::-;67097:14;::::0;::::5;:53:::0;67166:135:::5;::::0;67222:7;;67197:10:::5;::::0;67166:135:::5;::::0;::::5;::::0;67244:16;;67275:15;;67166:135:::5;:::i;59338:171::-:0;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;59417:13:::1;:30:::0;;-1:-1:-1;;59417:30:0::1;;::::0;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;59465:36:::1;::::0;::::1;::::0;-1:-1:-1;;59465:36:0::1;59338:171:::0;:::o;59517:179::-;59601:30;;:::i;:::-;59656:32;59683:4;59656:26;:32::i;:::-;59649:39;;59517:179;;:::o;62405:276::-;62527:7;62536;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;58123:11:::1;::::0;::::1;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::1;;;;;;;:::i;:::-;62561:25:::2;62589:21;:7;62601:8:::0;62589:11:::2;:21::i;:::-;62561:49;;62628:45;62641:8;62651:6;:21;;;62628:12;:45::i;:::-;2628:1:::0;3590:7;:22;62621:52;;;;-1:-1:-1;62405:276:0;-1:-1:-1;;;62405:276:0:o;57381:25::-;;;;;;;;;:::o;59162:168::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;59272:14:::1;:23:::0;;-1:-1:-1;;;;;;59272:23:0::1;-1:-1:-1::0;;;;;59272:23:0;;;::::1;::::0;;;::::1;::::0;;;59306:10:::1;:16:::0;59162:168::o;72254:805::-;72453:5;;72428:4;;-1:-1:-1;;;;;72453:15:0;;;:5;;:15;72445:61;;;;-1:-1:-1;;;72445:61:0;;;;;;;:::i;:::-;72517:12;72532:17;72542:6;72532:9;:17::i;:::-;72560:5;;72517:32;;-1:-1:-1;72560:45:0;;-1:-1:-1;;;;;72560:5:0;72587:8;72598:6;72560:18;:45::i;:::-;72671:5;;72638:59;;-1:-1:-1;;;72638:59:0;;57056:45;;-1:-1:-1;;;;;72638:20:0;;;;;;:59;;72659:10;;72671:5;;;72678:6;;72686:4;;72692;;;;72638:59;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:102;72616:180;;;;-1:-1:-1;;;72616:180:0;;;;;;;:::i;:::-;72807:124;72852:8;72884:4;72904:16;:6;72915:4;72904:10;:16::i;:::-;72807:5;;-1:-1:-1;;;;;72807:5:0;;:124;;:22;:124::i;:::-;72944:25;72964:4;72944:19;:25::i;:::-;73009:5;;72985:44;;72998:9;;72985:44;;;;-1:-1:-1;;;;;73009:5:0;;73016:6;;73024:4;;72985:44;:::i;:::-;;;;;;;;-1:-1:-1;73047:4:0;;72254:805;-1:-1:-1;;;;;;72254:805:0:o;73822:272::-;73957:5;;73928:7;;-1:-1:-1;;;;;73957:15:0;;;:5;;:15;73953:134;;;74003:5;;73996:38;;-1:-1:-1;;;73996:38:0;;-1:-1:-1;;;;;74003:5:0;;;;73996:23;;:38;;74028:4;;73996:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73989:45;;;;73953:134;-1:-1:-1;74074:1:0;74067:8;;62689:182;62755:7;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;58123:11:::1;::::0;::::1;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::1;;;;;;;:::i;:::-;62784:13:::2;::::0;::::2;::::0;::::2;;;62783:14;62775:50;;;;-1:-1:-1::0;;;62775:50:0::2;;;;;;;:::i;:::-;62845:18;:16;:18::i;:::-;62838:25;;2628:1:::0;3590:7;:22;62689:182;:::o;53563:550::-;53684:16;53707:20;53744:10;-1:-1:-1;;;;;53738:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53730:37;;53707:60;;53772:18;53807:8;-1:-1:-1;;;;;53801:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53793:35;;53772:56;;53852:10;53837:12;:25;53833:256;;;53881:51;53902:28;:12;53919:10;53902:16;:28::i;:::-;53881:11;;53897:2;:34;53881:15;:51::i;:::-;53870:62;;53833:256;;;53961:12;53948:10;:25;53944:145;;;53992:51;54013:28;:10;54028:12;54013:14;:28::i;:::-;53992:11;;54008:2;:34;53992:15;:51::i;53944:145::-;54072:11;54061:22;;53944:145;54093:15;;53563:550;;;;;:::o;57180:25::-;;;-1:-1:-1;;;;;57180:25:0;;:::o;56998:103::-;57056:45;56998:103;:::o;26507:19::-;;;-1:-1:-1;;;;;26507:19:0;;:::o;58183:241::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;58278:11:::1;;;;;;;;;-1:-1:-1::0;;;;;58278:11:0::1;-1:-1:-1::0;;;;;58278:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58269:35:0::1;:5;-1:-1:-1::0;;;;;58269:35:0::1;;;58247:112;;;;-1:-1:-1::0;;;58247:112:0::1;;;;;;;:::i;:::-;58370:4;:12:::0;;-1:-1:-1;;;;;;58370:12:0::1;-1:-1:-1::0;;;;;58370:12:0;::::1;::::0;;::::1;::::0;;;58398:18:::1;::::0;::::1;::::0;-1:-1:-1;;58398:18:0::1;58183:241:::0;:::o;69466:201::-;-1:-1:-1;;;;;69610:15:0;69561:7;69610:15;;;:5;:15;;;;;69643:16;;;;69466:201::o;57214:19::-;;;-1:-1:-1;;;;;57214:19:0;;:::o;57242:22::-;;;-1:-1:-1;;;;;57242:22:0;;:::o;57534:29::-;;;-1:-1:-1;;;;;57534:29:0;;:::o;68837:207::-;-1:-1:-1;;;;;68984:15:0;68935:7;68984:15;;;:5;:15;;;;;69017:19;;68837:207::o;68283:96::-;68328:7;68355:16;:7;:14;:16::i;69052:181::-;-1:-1:-1;;;;;69162:15:0;;69118:7;69162:15;;;:5;:15;;;;;69195:30;69162:15;69220:4;69195:24;:30::i;:::-;69188:37;69052:181;-1:-1:-1;;;69052:181:0:o;68608:221::-;68708:7;;68761:21;:7;68773:8;68761:11;:21::i;:::-;68800;;;;68608:221;-1:-1:-1;;;68608:221:0:o;63685:687::-;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;55225:22:::1;:20;:22::i;:::-;70314:32:::2;70322:10;70314:30;:32::i;:::-;70313:33;:60;;;;-1:-1:-1::0;70350:10:0::2;70364:9;70350:23;70313:60;70291:142;;;;-1:-1:-1::0;;;70291:142:0::2;;;;;;;:::i;:::-;58123:11:::3;::::0;::::3;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::3;;;;;;;:::i;:::-;63862:13:::4;::::0;::::4;::::0;::::4;;;63861:14;63853:50;;;;-1:-1:-1::0;;;63853:50:0::4;;;;;;;:::i;:::-;63946:10;63916:21;63940:17:::0;;;:5:::4;:17;::::0;;;;63968::::4;63940::::0;63980:4:::4;63968:11;:17::i;:::-;63998:5;::::0;:58:::4;::::0;-1:-1:-1;;;;;63998:5:0::4;64021:10;64041:4;64048:7:::0;63998:22:::4;:58::i;:::-;64086:14;::::0;:27:::4;::::0;64105:7;64086:18:::4;:27::i;:::-;64069:14;:44:::0;64148:19;;:32:::4;::::0;64172:7;64148:23:::4;:32::i;:::-;64126:54:::0;;64210:12:::4;64191:16;::::0;::::4;:31:::0;64250:14:::4;::::0;64239:25;::::4;64235:76;;64281:18;:16;:18::i;:::-;;64235:76;64328:36;::::0;64356:7;;64344:10:::4;::::0;64328:36:::4;::::0;;;::::4;-1:-1:-1::0;;2628:1:0;3590:7;:22;63685:687::o;57606:31::-;;;-1:-1:-1;;;;;57606:31:0;;:::o;59704:460::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;59783:11:::1;::::0;::::1;;59782:12;59774:44;;;;-1:-1:-1::0;;;59774:44:0::1;;;;;;;:::i;:::-;59859:11;;;;;;;;;-1:-1:-1::0;;;;;59859:11:0::1;-1:-1:-1::0;;;;;59859:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59851:4;::::0;-1:-1:-1;;;;;59851:4:0;;::::1;:34:::0;::::1;;;59829:121;;;;-1:-1:-1::0;;;59829:121:0::1;;;;;;;:::i;:::-;59994:11;;;;;;;;;-1:-1:-1::0;;;;;59994:11:0::1;-1:-1:-1::0;;;;;59994:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59983:7;::::0;-1:-1:-1;;;;;59983:7:0;;::::1;:37:::0;::::1;;;59961:127;;;;-1:-1:-1::0;;;59961:127:0::1;;;;;;;:::i;:::-;60099:28;60118:8;60099:18;:28::i;:::-;-1:-1:-1::0;60138:11:0::1;:18:::0;;-1:-1:-1;;60138:18:0::1;60152:4;60138:18;::::0;;59704:460::o;67372:903::-;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;55225:22:::1;:20;:22::i;:::-;70314:32:::2;70322:10;70314:30;:32::i;:::-;70313:33;:60;;;;-1:-1:-1::0;70350:10:0::2;70364:9;70350:23;70313:60;70291:142;;;;-1:-1:-1::0;;;70291:142:0::2;;;;;;;:::i;:::-;70020:10:::3;::::0;:14;70016:208:::3;;70110:14;::::0;70099:41:::3;::::0;;-1:-1:-1;;;70099:41:0;;;;70051:20:::3;::::0;-1:-1:-1;;;;;70110:14:0::3;::::0;70099:39:::3;::::0;:41:::3;::::0;;::::3;::::0;::::3;::::0;;;;;;;;70110:14;70099:41;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70051:90;;70179:10;;70164:12;:25;70156:56;;;;-1:-1:-1::0;;;70156:56:0::3;;;;;;;:::i;:::-;70016:208;;58123:11:::4;::::0;::::4;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::4;;;;;;;:::i;:::-;67590:10:::5;67560:21;67584:17:::0;;;:5:::5;:17;::::0;;;;67612::::5;67584::::0;67624:4:::5;67612:11;:17::i;:::-;67665:16;::::0;::::5;::::0;67698:22;;::::5;67694:356;;;67737:24;67764:25;:7:::0;67776:12;67764:11:::5;:25::i;:::-;67821:14;::::0;::::5;::::0;67737:52;;-1:-1:-1;67821:36:0::5;::::0;67737:52;67821:18:::5;:36::i;:::-;67804:14;::::0;::::5;:53:::0;67891:1:::5;67872:16;::::0;::::5;:20:::0;67907:54:::5;::::0;;;;::::5;::::0;;;::::5;::::0;;::::5;;::::0;::::5;::::0;::::5;::::0;67804:4;;67924::::5;::::0;67907:16:::5;:54::i;:::-;67694:356;;;;68013:25;:12:::0;68030:7;68013:16:::5;:25::i;:::-;67994:16;::::0;::::5;:44:::0;67694:356:::5;68094:5;::::0;68101:10:::5;::::0;68060:12:::5;::::0;68075:46:::5;::::0;-1:-1:-1;;;;;68094:5:0;;::::5;::::0;68101:10:::5;68113:7:::0;68075:18:::5;:46::i;:::-;68147:10;::::0;68132:49:::5;::::0;-1:-1:-1;;;68132:49:0;;68060:61;;-1:-1:-1;;;;;;68147:10:0::5;::::0;68132:31:::5;::::0;:49:::5;::::0;68164:10:::5;::::0;68060:61;;68132:49:::5;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::5;;;;;;;;;;;;::::0;::::5;;;;;;;;;68207:14;;68196:7;:25;68192:76;;68238:18;:16;:18::i;:::-;;68192:76;-1:-1:-1::0;;2628:1:0;3590:7;:22;-1:-1:-1;;67372:903:0:o;60172:121::-;58123:11;;;;58115:40;;;;-1:-1:-1;;;58115:40:0;;;;;;;:::i;:::-;26734:4:::1;::::0;-1:-1:-1;;;;;26734:4:0::1;26720:10;:18;26712:40;;;;-1:-1:-1::0;;;26712:40:0::1;;;;;;;:::i;:::-;60257:28:::2;60276:8;60257:18;:28::i;:::-;60172:121:::0;:::o;65401:1049::-;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;55225:22:::1;:20;:22::i;:::-;70314:32:::2;70322:10;70314:30;:32::i;:::-;70313:33;:60;;;;-1:-1:-1::0;70350:10:0::2;70364:9;70350:23;70313:60;70291:142;;;;-1:-1:-1::0;;;70291:142:0::2;;;;;;;:::i;:::-;70020:10:::3;::::0;:14;70016:208:::3;;70110:14;::::0;70099:41:::3;::::0;;-1:-1:-1;;;70099:41:0;;;;70051:20:::3;::::0;-1:-1:-1;;;;;70110:14:0::3;::::0;70099:39:::3;::::0;:41:::3;::::0;;::::3;::::0;::::3;::::0;;;;;;;;70110:14;70099:41;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70051:90;;70179:10;;70164:12;:25;70156:56;;;;-1:-1:-1::0;;;70156:56:0::3;;;;;;;:::i;:::-;70016:208;;58123:11:::4;::::0;::::4;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::4;;;;;;;:::i;:::-;65646:10:::5;65616:21;65640:17:::0;;;:5:::5;:17;::::0;;;;65668::::5;65640::::0;65680:4:::5;65668:11;:17::i;:::-;65702::::0;;65698:161:::5;;65736:5;::::0;:64:::5;::::0;-1:-1:-1;;;;;65736:5:0::5;65759:10;65779:4;65786:13:::0;65736:22:::5;:64::i;:::-;65815:32;65833:13;65815:17;:32::i;:::-;65926:10;::::0;65938:5:::5;::::0;65871:20:::5;::::0;65907:51:::5;::::0;-1:-1:-1;;;;;65926:10:0;;::::5;::::0;65938:5:::5;65945:12:::0;65907:18:::5;:51::i;:::-;65871:87:::0;-1:-1:-1;66020:16:0;;66016:229:::5;;66068:10;::::0;66053:61:::5;::::0;-1:-1:-1;;;66053:61:0;;-1:-1:-1;;;;;66068:10:0;;::::5;::::0;66053:35:::5;::::0;:61:::5;::::0;66089:10:::5;::::0;66101:12;;66053:61:::5;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::5;;;;;;;;;;;;::::0;::::5;;;;;-1:-1:-1::0;;66144:10:0::5;::::0;66129:55:::5;::::0;-1:-1:-1;;;66129:55:0;;-1:-1:-1;;;;;66144:10:0;;::::5;::::0;-1:-1:-1;66129:41:0::5;::::0;-1:-1:-1;66129:55:0::5;::::0;66171:12;;66129:55:::5;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::5;;;;;;;;;;;;::::0;::::5;;;;;;;;;66016:229;;;66232:1;66217:16;;66016:229;66257:20;66280:31;:13:::0;66298:12;66280:17:::5;:31::i;:::-;66339:14;::::0;::::5;::::0;66257:54;;-1:-1:-1;66339:32:0::5;::::0;66257:54;66339:18:::5;:32::i;:::-;66322:14;::::0;::::5;:49:::0;66389:53:::5;::::0;66429:12;;66414:13;;66402:10:::5;::::0;66389:53:::5;::::0;;;::::5;-1:-1:-1::0;;2628:1:0;3590:7;:22;-1:-1:-1;;;65401:1049:0:o;73067:247::-;73218:5;;73185:7;;-1:-1:-1;;;;;73218:15:0;;;:5;;:15;73210:61;;;;-1:-1:-1;;;73210:61:0;;;;;;;:::i;:::-;73289:17;73299:6;73289:9;:17::i;:::-;73282:24;;73067:247;;;;;:::o;60745:470::-;58123:11;;60843:7;;;;58123:11;;58115:40;;;;-1:-1:-1;;;58115:40:0;;;;;;;:::i;:::-;60877:25:::1;60905:21;:7;60917:8:::0;60905:11:::1;:21::i;:::-;60877:49:::0;-1:-1:-1;60940:24:0::1;::::0;61006:29:::1;60877:49:::0;61029:4:::1;61006:14;:29::i;:::-;60939:96;;;;61048:37;61068:16;61048:19;:37::i;:::-;61103:49;::::0;61136:15;;61118:16;;61103:49:::1;::::0;;;::::1;61173:16:::0;;-1:-1:-1;61191:15:0;-1:-1:-1;;60745:470:0;;;:::o;58889:265::-;26734:4;;-1:-1:-1;;;;;26734:4:0;26720:10;:18;26712:40;;;;-1:-1:-1;;;26712:40:0;;;;;;;:::i;:::-;58993:11:::1;;;;;;;;;-1:-1:-1::0;;;;;58993:11:0::1;-1:-1:-1::0;;;;;58993:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58981:38:0::1;:8;-1:-1:-1::0;;;;;58981:38:0::1;;;58959:118;;;;-1:-1:-1::0;;;58959:118:0::1;;;;;;;:::i;:::-;59088:7;:18:::0;;-1:-1:-1;;;;;;59088:18:0::1;-1:-1:-1::0;;;;;59088:18:0;::::1;::::0;;::::1;::::0;;;59122:24:::1;::::0;::::1;::::0;-1:-1:-1;;59122:24:0::1;58889:265:::0;:::o;57311:29::-;;;;:::o;69241:217::-;-1:-1:-1;;;;;69385:15:0;;69336:7;69385:15;;;:5;:15;;;;;69418:32;69385:15;69445:4;69418:26;:32::i;57132:20::-;;;-1:-1:-1;;;;;57132:20:0;;:::o;62181:216::-;62317:7;62326;2672:1;3278:7;;:19;;3270:63;;;;-1:-1:-1;;;3270:63:0;;;;;;;:::i;:::-;2672:1;3411:7;:18;58123:11:::1;::::0;::::1;;58115:40;;;;-1:-1:-1::0;;;58115:40:0::1;;;;;;;:::i;:::-;62358:31:::2;62371:8;62381:7;62358:12;:31::i;57273:29::-:0;;;;:::o;35580:125::-;35652:12;35678:5;:14;;35693:6;35678:22;;;;;;;;;;;;;;;;;;35671:29;;35580:125;;;;:::o;55018:98::-;55090:4;-1:-1:-1;;;;;55099:8:0;55082:25;;55074:34;;;;;;55018:98::o;4415:422::-;4782:20;4821:8;;;4415:422::o;38062:470::-;38134:20;38157:26;:5;38178:4;38157:20;:26::i;:::-;38134:49;;38207:5;:15;;;38192:12;:30;38188:273;;;38258:15;;;;;38230:25;38279:19;;;38324:35;:12;38258:15;38324:16;:35::i;:::-;38304:17;;;:55;-1:-1:-1;38188:273:0;;;38397:1;38377:17;;;:21;38422:15;;;;:33;;38442:12;38422:19;:33::i;:::-;38404:15;;;:51;38188:273;-1:-1:-1;38500:27:0;;38465:62;:32;;;;:62;38062:470::o;71169:1061::-;71366:5;;71359:38;;-1:-1:-1;;;71359:38:0;;71268:7;;;;;;71341:57;;71350:7;;-1:-1:-1;;;;;71366:5:0;;71359:23;;:38;;71391:4;;71359:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71341:8;:57::i;:::-;71302:96;-1:-1:-1;;;;;;71415:27:0;;71437:4;71415:27;71411:107;;71459:5;;:47;;-1:-1:-1;;;;;71459:5:0;71478:10;71490:15;71459:18;:47::i;:::-;71556:15;;71530:23;71668:28;:7;71556:15;71668:11;:28::i;:::-;71641:55;-1:-1:-1;71711:20:0;;71707:387;;71748:31;71782:14;:7;:12;:14::i;:::-;71748:48;-1:-1:-1;71812:23:0;;71881:51;71748:48;71903:10;71915:16;71881:21;:51::i;:::-;71811:121;;-1:-1:-1;71811:121:0;-1:-1:-1;71967:36:0;:15;71811:121;71967:19;:36::i;:::-;71949:54;-1:-1:-1;72041:41:0;:20;72066:15;72041:24;:41::i;:::-;72018:64;;71707:387;;;;72123:14;;:40;;72142:20;72123:18;:40::i;:::-;72106:14;:57;-1:-1:-1;72184:15:0;;-1:-1:-1;72201:20:0;-1:-1:-1;;71169:1061:0;;;;;;:::o;17312:166::-;17398:7;17434:12;17426:6;;;;17418:29;;;;-1:-1:-1;;;17418:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;17465:5:0;;;17312:166::o;38537:156::-;38660:21;:5;38676:4;38660:15;:21::i;:::-;38683:4;38652:36;;;;;-1:-1:-1;;;38652:36:0;;;;;;;;:::i;:::-;;38537:156;;;:::o;62879:798::-;62925:7;62945:31;62979:14;:7;:12;:14::i;:::-;63029:5;;63022:38;;-1:-1:-1;;;63022:38:0;;62945:48;;-1:-1:-1;63004:15:0;;-1:-1:-1;;;;;63029:5:0;;;;63022:23;;:38;;63054:4;;63022:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63087:11;;:62;;-1:-1:-1;;;63087:62:0;;63004:56;;-1:-1:-1;63071:13:0;;-1:-1:-1;;;;;63087:11:0;;;;:26;;:62;;-1:-1:-1;;;36894:33:0;63087:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63071:78;;63160:20;63196:108;63270:11;;;;;;;;;-1:-1:-1;;;;;63270:11:0;-1:-1:-1;;;;;63270:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63196:51;63241:5;63196:40;63208:12;:27;;;63196:7;:11;;:40;;;;:::i;:::-;:44;;:51::i;:::-;:73;;:108::i;:::-;63160:144;;63334:12;:27;;;63319:12;:42;63315:355;;;63378:24;63422:107;63465:45;63482:12;:27;;;63465:12;:16;;:45;;;;:::i;:::-;63422:12;;:20;:107::i;:::-;63549:30;;63378:151;;-1:-1:-1;63378:151:0;;63549:30;;;;;63601:16;-1:-1:-1;63594:23:0;;-1:-1:-1;;;;63594:23:0;63315:355;63657:1;63650:8;;;;;;;;69675:299;69756:4;;69738:5;;:31;;-1:-1:-1;;;;;69738:5:0;;;;69756:4;69762:6;69738:17;:31::i;:::-;69786:4;;;69780:45;;-1:-1:-1;;;69780:45:0;;-1:-1:-1;;;;;69786:4:0;;;;69780:22;;:45;;69811:4;;69818:6;;69780:45;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69876:5:0;;69883:10;;69836:18;;-1:-1:-1;69857:45:0;;-1:-1:-1;;;;;;69876:5:0;;;;69883:10;69895:6;69857:18;:45::i;:::-;69928:10;;69913:53;;-1:-1:-1;;;69913:53:0;;69836:66;;-1:-1:-1;;;;;;69928:10:0;;69913:41;;:53;;69836:66;;69913:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69675:299;;:::o;14947:158::-;15005:7;15038:1;15033;:6;;15025:49;;;;-1:-1:-1;;;15025:49:0;;;;;;;:::i;:::-;-1:-1:-1;15092:5:0;;;14947:158::o;38886:314::-;38963:30;;:::i;:::-;39011:184;;;;;;;;39041:148;39144:4;:16;;;;;;;;;;-1:-1:-1;;;;;39144:16:0;-1:-1:-1;;;;;39144:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39077:16;;:54;;-1:-1:-1;;;39077:54:0;;39041:91;;-1:-1:-1;;;;;39077:16:0;;:31;;:54;;-1:-1:-1;;;36730:20:0;39077:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37758:19;;39041:35;:91::i;:148::-;39011:184;;39000:195;38886:314;-1:-1:-1;;38886:314:0:o;70461:700::-;70610:13;;70554:7;;;;70610:13;;;;;;:52;;-1:-1:-1;70658:4:0;;-1:-1:-1;;;;;70658:4:0;70644:10;:18;70610:52;:104;;;;70695:19;:7;:17;:19::i;:::-;70683:8;:31;;70610:104;70588:255;;;;-1:-1:-1;;;70588:255:0;;;;;;;:::i;:::-;70856:25;70884:21;:7;70896:8;70884:11;:21::i;:::-;70856:49;-1:-1:-1;70917:24:0;;70983:39;70856:49;71007:4;71014:7;70983:15;:39::i;:::-;70916:106;;;;71054:8;71040:58;71064:16;71082:15;71040:58;;;;;;;:::i;:::-;;;;;;;;71119:16;;;;-1:-1:-1;70461:700:0;-1:-1:-1;;;;70461:700:0:o;73322:313::-;73428:11;;:66;;-1:-1:-1;;;73428:66:0;;73380:7;;;;-1:-1:-1;;;;;73428:11:0;;;;:26;;:66;;36998:37;;73428:66;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73400:94;;73505:27;73535:11;;;;;;;;;-1:-1:-1;;;;;73535:11:0;-1:-1:-1;;;;;73535:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73505:63;-1:-1:-1;73586:41:0;73505:63;73586:16;:6;73597:4;73586:10;:16::i;:41::-;73579:48;73322:313;-1:-1:-1;;;;73322:313:0:o;30246:361::-;30395:12;30409:17;30430:5;-1:-1:-1;;;;;30430:10:0;30464;30476:2;30480:5;30441:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30441:45:0;;;;;;;;;;;30430:57;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30394:93;;;;30506:7;:57;;;;-1:-1:-1;30518:11:0;;:16;;:44;;;30549:4;30538:24;;;;;;;;;;;;:::i;:::-;30498:101;;;;-1:-1:-1;;;30498:101:0;;;;;;;:::i;:::-;30246:361;;;;;:::o;14485:179::-;14543:7;14575:5;;;14599:6;;;;14591:46;;;;-1:-1:-1;;;14591:46:0;;;;;;;:::i;30615:402::-;30794:12;30808:17;30829:5;-1:-1:-1;;;;;30829:10:0;30863;30875:4;30881:2;30885:5;30840:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30840:51:0;;;;;;;;;;;30829:63;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30793:99;;;;30911:7;:57;;;;-1:-1:-1;30923:11:0;;:16;;:44;;;30954:4;30943:24;;;;;;;;;;;;:::i;:::-;30903:106;;;;-1:-1:-1;;;30903:106:0;;;;;;;:::i;61223:950::-;61292:10;;61288:878;;61337:11;;:57;;-1:-1:-1;;;61337:57:0;;61319:15;;-1:-1:-1;;;;;61337:11:0;;:26;;:57;;-1:-1:-1;;;36801:28:0;61337:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61319:75;;61409:18;61431:58;61455:11;;;;;;;;;-1:-1:-1;;;;;61455:11:0;-1:-1:-1;;;;;61455:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61431:19;:6;61442:7;61431:10;:19::i;:58::-;61409:80;-1:-1:-1;61504:25:0;61532:22;:6;61409:80;61532:10;:22::i;:::-;61575:14;;61504:50;;-1:-1:-1;61575:18:0;61571:360;;61614:38;;:::i;:::-;61676:110;61749:14;;61676:42;61700:17;61676:23;:42::i;:::-;:46;;:110::i;:::-;61835:31;;;;;;;;;:27;:31;;;61614:172;;-1:-1:-1;61835:80:0;;61614:172;61835:31;:80::i;:::-;61805:110;:27;:110;-1:-1:-1;61571:360:0;61951:14;;61947:94;;62005:7;;61986:5;;:39;;-1:-1:-1;;;;;61986:5:0;;;;62005:7;62014:10;61986:18;:39::i;:::-;62061:21;;62057:98;;62103:36;62121:17;62103;:36::i;16062:153::-;16120:7;16152:1;16148;:5;16140:44;;;;-1:-1:-1;;;16140:44:0;;;;;;;:::i;:::-;16206:1;16202;:5;;;;;;;16062:153;-1:-1:-1;;;16062:153:0:o;15364:220::-;15422:7;15446:6;15442:20;;-1:-1:-1;15461:1:0;15454:8;;15442:20;15485:5;;;15489:1;15485;:5;:1;15509:5;;;;;:10;15501:56;;;;-1:-1:-1;;;15501:56:0;;;;;;;:::i;36455:106::-;36535:21;;36455:106::o;39205:397::-;39299:7;;39339:26;:5;39360:4;39339:20;:26::i;:::-;39313:52;-1:-1:-1;39374:20:0;39370:60;;-1:-1:-1;;39409:15:0;;;;39402:22;;39370:60;39464:15;;;;39488:36;;;39484:62;;39539:1;39532:8;;;;;;39484:62;39559:38;:17;39581:15;39559:21;:38::i;:::-;39552:45;39205:397;-1:-1:-1;;;;;39205:397:0:o;60301:436::-;60401:11;;;;;;;;;-1:-1:-1;;;;;60401:11:0;-1:-1:-1;;;;;60401:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60389:38:0;:8;-1:-1:-1;;;;;60389:38:0;;;60367:123;;;;-1:-1:-1;;;60367:123:0;;;;;;;:::i;:::-;60586:5;;60567:15;;;-1:-1:-1;;;60567:15:0;;;;60539:8;;-1:-1:-1;;;;;60586:5:0;;;;60567:13;;;;;;:15;;;;;;;;;;;;;;;:13;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60567:24:0;;60559:52;;;;-1:-1:-1;;;60559:52:0;;;;;;;:::i;:::-;60635:49;;;;;;;;;-1:-1:-1;;;;;60635:49:0;;;;-1:-1:-1;60635:49:0;;;;60622:63;;:7;;:12;:63::i;:::-;60701:28;;-1:-1:-1;;;;;60701:28:0;;;;;;;;60301:436;;:::o;34731:311::-;34806:7;34815;34855:5;:20;;;34833:18;:5;:16;:18::i;:::-;:42;34829:73;;-1:-1:-1;34891:1:0;;-1:-1:-1;34891:1:0;34883:13;;34829:73;34906:23;34932:44;34955:5;:20;;;34932:18;:5;:16;:18::i;:::-;:22;;:44::i;:::-;34906:70;-1:-1:-1;34988:49:0;:5;35009:10;34906:70;34988:20;:49::i;:::-;34981:56;;;;;34731:311;;;;;:::o;39607:424::-;39703:7;;39743:26;:5;39764:4;39743:20;:26::i;:::-;39717:52;-1:-1:-1;39778:20:0;39774:62;;-1:-1:-1;;39813:17:0;;;;39806:24;;39774:62;39870:15;;;;39894:36;;;39890:62;;39945:1;39938:8;;;;;;39890:62;39965:61;39987:38;:15;40007:17;39987:19;:38::i;:::-;39965:17;;;;;:21;:61::i;40036:509::-;40125:7;40139:61;;:::i;:::-;-1:-1:-1;40139:91:0;;;;;;;;;40203:27;;;40139:91;;;40235:58;;:::i;:::-;-1:-1:-1;40235:93:0;;;;;;;;;40296:32;;;40235:93;;;40339:63;:30;40235:93;40339:34;:63::i;:::-;40335:94;;40422:1;40415:8;;;;;;40335:94;40510:20;;40442:98;;:89;;:63;:30;40477:27;40442:34;:63::i;:::-;:67;;:89::i;:::-;:96;:98::i;481:106::-;539:7;570:1;566;:5;:13;;578:1;566:13;;;-1:-1:-1;574:1:0;;481:106;-1:-1:-1;481:106:0:o;35882:121::-;35939:12;35965:5;35980:17;35965:5;35980:15;:17::i;:::-;35965:33;;;;;;;;;;;;;;;;;;35958:40;;35882:121;;;:::o;33118:345::-;33224:7;;;;33301:41;:5;33322:10;33334:7;33301:20;:41::i;:::-;33370:20;;;;33247:95;;-1:-1:-1;33247:95:0;-1:-1:-1;33370:41:0;;33247:95;33370:24;:41::i;:::-;33347:20;;;:64;33424:16;;-1:-1:-1;33442:15:0;-1:-1:-1;33118:345:0;;;;;;:::o;38698:183::-;38782:4;;38800:71;38833:37;:5;38865:4;38833:31;:37::i;:::-;38800:28;38823:4;38800:22;:28::i;:::-;:32;;:71::i;:::-;:76;;;38698:183;-1:-1:-1;;;38698:183:0:o;32567:367::-;32639:7;32725:14;32742:13;:5;:11;:13::i;:::-;32788;;32725:30;;-1:-1:-1;32760:52:0;;-1:-1:-1;;;;;32760:19:0;;;;32788:13;32804:7;32760:19;:52::i;:::-;32817:13;;:30;;-1:-1:-1;;;32817:30:0;;-1:-1:-1;;;;;32817:13:0;;;;:21;;:30;;32839:7;;32817:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32875:20:0;;;;:33;;-1:-1:-1;32900:7:0;32875:24;:33::i;:::-;32852:20;;;:56;-1:-1:-1;32922:7:0;;-1:-1:-1;32567:367:0;;;;:::o;29880:358::-;30027:12;30041:17;30062:5;-1:-1:-1;;;;;30062:10:0;30096;30108:2;30112:5;30073:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30073:45:0;;;;;;;;;;;30062:57;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30026:93;;;;30138:7;:57;;;;-1:-1:-1;30150:11:0;;:16;;:44;;;30181:4;30170:24;;;;;;;;;;;;:::i;:::-;30130:100;;;;-1:-1:-1;;;30130:100:0;;;;;;;:::i;36194:160::-;36256:7;36270:15;36288:14;:5;:12;:14::i;:::-;36270:32;;36314:35;36326:1;36314:35;;;;;;;;;;;;;-1:-1:-1;;;36314:35:0;;;:7;:11;;:35;;;;;:::i;28047:188::-;28103:15;;:::i;:::-;28127:9;28151:10;;;:52;;-1:-1:-1;;27984:12:0;28170:14;;;;28165:29;;:38;;28151:52;28143:61;;;;;;28218:11;;;;;;;;;;;;;28047:188;-1:-1:-1;;28047:188:0:o;29245:160::-;29318:15;;:::i;:::-;29350:10;29342:19;;;;;;29375:24;;;;;;;;29393:5;29384:4;:6;;;:14;;;;;;29375:24;;29368:31;29245:160;-1:-1:-1;;;29245:160:0:o;28352:193::-;28433:15;;:::i;:::-;28507:6;;28495:7;;28486:16;;;28481:32;;;28473:41;;;;;;28528:11;;;;;;;;;;;;;28352:193;-1:-1:-1;;;28352:193:0:o;35134:295::-;35209:9;35204:187;35228:21;;35224:25;;35204:187;;;35339:5;:14;;35354:1;35339:17;;;;;;;;;;;;;;;;;;;;;:25;35310:16;;-1:-1:-1;;;;;35302:63:0;;;35339:25;;35302:63;;35294:91;;;;-1:-1:-1;;;35294:91:0;;;;;;;:::i;:::-;35251:3;;35204:187;;;-1:-1:-1;35395:29:0;;;;;;;;-1:-1:-1;35395:29:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;35395:29:0;-1:-1:-1;;;;;35395:29:0;;;;;;;;;;;;;;;;;35134:295::o;32130:115::-;32214:13;;:26;;;-1:-1:-1;;;32214:26:0;;;;32193:7;;-1:-1:-1;;;;;32214:13:0;;:24;;:26;;;;;;;;;;;;;;:13;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;33656:654::-;33768:7;33777;33791:14;33808:13;:5;:11;:13::i;:::-;33791:30;;33828:24;33862:6;-1:-1:-1;;;;;33855:24:0;;33880:10;33855:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33828:63;;33896:27;33926:18;:5;:16;:18::i;:::-;33951:13;;:43;;-1:-1:-1;;;33951:43:0;;33896:48;;-1:-1:-1;;;;;;33951:13:0;;:22;;:43;;33974:10;;33986:7;;33951:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;34026:36:0;;-1:-1:-1;;;34026:36:0;;34001:22;;-1:-1:-1;;;;;;34026:24:0;;;-1:-1:-1;34026:24:0;;:36;;34051:10;;34026:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34001:61;-1:-1:-1;34067:24:0;34094:36;34001:61;34113:16;34094:18;:36::i;:::-;34067:63;;34137:25;34165:18;:5;:16;:18::i;:::-;34137:46;-1:-1:-1;34188:23:0;34214:42;:19;34137:46;34214:23;:42::i;:::-;34271:16;;;;-1:-1:-1;33656:654:0;;-1:-1:-1;;;;;;;;;;33656:654:0:o;29411:221::-;29520:7;;29511:6;;29492;;-1:-1:-1;29507:48:0;;;-1:-1:-1;;;29538:9:0;;29507:48;29576:7;;29567:6;;:16;29563:47;;;-1:-1:-1;29601:1:0;29594:8;;29563:47;-1:-1:-1;29625:1:0;29411:221;;;;:::o;28693:193::-;28774:15;;:::i;:::-;28848:6;;28836:7;;28827:16;;;28822:32;;;28814:41;;;;;29034:205;29107:15;;:::i;:::-;29131:9;29155:10;;;:52;;-1:-1:-1;;29201:6:0;;29174:14;;;;29192:5;29174:14;29192:5;29169:28;;;;;:38;29155:52;29147:61;;;;;29638:105;29722:6;27984:12;29722:15;;;29638:105::o;40550:351::-;40659:30;;:::i;:::-;40698:18;40719:31;:5;40745:4;40719:25;:31::i;:::-;40698:52;-1:-1:-1;40759:15:0;40755:69;;40789:29;:27;:29::i;:::-;40782:36;;;;;40755:69;40835:61;40885:10;40835:45;40859:5;:20;;;40835:23;:45::i;32340:105::-;32419:13;;:21;;;-1:-1:-1;;;32419:21:0;;;;32398:7;;-1:-1:-1;;;;;32419:13:0;;:19;;:21;;;;;;;;;;;;;;:13;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;28241:105::-;28288:15;;:::i;:::-;-1:-1:-1;28319:21:0;;;;;;;;;-1:-1:-1;;28319:21:0;;28241:105;:::o;-1:-1:-1:-;;;;;;;;;;;;;;:::o;1797:241::-;;1901:2;1889:9;1880:7;1876:23;1872:32;1869:2;;;-1:-1;;1907:12;1869:2;85:6;72:20;97:33;124:5;97:33;:::i;2045:263::-;;2160:2;2148:9;2139:7;2135:23;2131:32;2128:2;;;-1:-1;;2166:12;2128:2;226:6;220:13;238:33;265:5;238:33;:::i;2315:491::-;;;;2453:2;2441:9;2432:7;2428:23;2424:32;2421:2;;;-1:-1;;2459:12;2421:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;2511:63;-1:-1;2611:2;2650:22;;72:20;97:33;72:20;97:33;:::i;:::-;2415:391;;2619:63;;-1:-1;;;2719:2;2758:22;;;;1449:20;;2415:391::o;2813:366::-;;;2934:2;2922:9;2913:7;2909:23;2905:32;2902:2;;;-1:-1;;2940:12;2902:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;2992:63;3092:2;3131:22;;;;1449:20;;-1:-1;;;2896:283::o;3186:235::-;;3287:2;3275:9;3266:7;3262:23;3258:32;3255:2;;;-1:-1;;3293:12;3255:2;360:6;347:20;372:30;396:5;372:30;:::i;3428:257::-;;3540:2;3528:9;3519:7;3515:23;3511:32;3508:2;;;-1:-1;;3546:12;3508:2;495:6;489:13;507:30;531:5;507:30;:::i;3692:263::-;;3807:2;3795:9;3786:7;3782:23;3778:32;3775:2;;;-1:-1;;3813:12;3775:2;-1:-1;627:13;;3769:186;-1:-1;3769:186::o;3962:799::-;;;;;;4165:3;4153:9;4144:7;4140:23;4136:33;4133:2;;;-1:-1;;4172:12;4133:2;1157:6;1144:20;1169:62;1225:5;1169:62;:::i;:::-;4224:92;-1:-1;4353:2;4392:22;;72:20;97:33;72:20;97:33;:::i;:::-;4361:63;-1:-1;4461:2;4500:22;;1449:20;;-1:-1;4597:2;4582:18;;4569:32;4621:18;4610:30;;;4607:2;;;-1:-1;;4643:12;4607:2;4728:6;4717:9;4713:22;;;818:3;811:4;803:6;799:17;795:27;785:2;;-1:-1;;826:12;785:2;869:6;856:20;4621:18;888:6;885:30;882:2;;;-1:-1;;918:12;882:2;1013:3;4353:2;993:17;954:6;979:32;;976:41;973:2;;;-1:-1;;1020:12;973:2;4127:634;;;;-1:-1;4127:634;;-1:-1;4353:2;950:17;;4663:82;4127:634;-1:-1;;;4127:634::o;5036:241::-;;5140:2;5128:9;5119:7;5115:23;5111:32;5108:2;;;-1:-1;;5146:12;5108:2;-1:-1;1449:20;;5102:175;-1:-1;5102:175::o;5554:366::-;;;5675:2;5663:9;5654:7;5650:23;5646:32;5643:2;;;-1:-1;;5681:12;5643:2;-1:-1;;1449:20;;;5833:2;5872:22;;;1449:20;;-1:-1;5637:283::o;5927:259::-;;6040:2;6028:9;6019:7;6015:23;6011:32;6008:2;;;-1:-1;;6046:12;6008:2;1742:6;1736:13;36891:4;39309:5;36880:16;39286:5;39283:33;39273:2;;-1:-1;;39320:12;18437:271;;7181:5;35473:12;7292:52;7337:6;7332:3;7325:4;7318:5;7314:16;7292:52;:::i;:::-;7356:16;;;;;18571:137;-1:-1;;18571:137::o;18715:222::-;-1:-1;;;;;36675:54;;;;6413:37;;18842:2;18827:18;;18813:124::o;18944:788::-;-1:-1;;;;;36675:54;;;6272:58;;36675:54;;19392:2;19377:18;;6413:37;19475:2;19460:18;;6644:37;;;19558:2;19543:18;;6644:37;;;36686:42;19595:3;19580:19;;19573:49;;;19204:19;;35746;;;18944:788;35758:6;37973:3;35786:14;;;37955:30;38016:16;;;35786:14;38016:16;;;38009:27;;;;38411:7;38395:14;;;-1:-1;;38391:28;6968:39;;;19190:542;-1:-1;;;;;19190:542::o;19739:349::-;-1:-1;;;;;36675:54;;;;6272:58;;20074:2;20059:18;;6644:37;19902:2;19887:18;;19873:215::o;20095:444::-;-1:-1;;;;;36675:54;;;6413:37;;36675:54;;;;20442:2;20427:18;;6413:37;20525:2;20510:18;;6644:37;;;;20278:2;20263:18;;20249:290::o;20886:444::-;-1:-1;;;;;36675:54;;;;6413:37;;21233:2;21218:18;;6644:37;;;;21316:2;21301:18;;6644:37;21069:2;21054:18;;21040:290::o;21337:210::-;36303:13;;36296:21;6527:34;;21458:2;21443:18;;21429:118::o;21554:222::-;6644:37;;;21681:2;21666:18;;21652:124::o;22323:310::-;;22470:2;22491:17;22484:47;7877:5;35473:12;35758:6;22470:2;22459:9;22455:18;35746:19;7971:52;8016:6;35786:14;22459:9;35786:14;22470:2;7997:5;7993:16;7971:52;:::i;:::-;38411:7;38395:14;-1:-1;;38391:28;8035:39;;;;35786:14;8035:39;;22441:192;-1:-1;;22441:192::o;22640:416::-;22840:2;22854:47;;;8311:2;22825:18;;;35746:19;8347:33;35786:14;;;8327:54;8400:12;;;22811:245::o;23063:416::-;23263:2;23277:47;;;8651:2;23248:18;;;35746:19;-1:-1;;;35786:14;;;8667:38;8724:12;;;23234:245::o;23486:416::-;23686:2;23700:47;;;8975:2;23671:18;;;35746:19;9011:34;35786:14;;;8991:55;-1:-1;;;9066:12;;;9059:25;9103:12;;;23657:245::o;23909:416::-;24109:2;24123:47;;;9354:2;24094:18;;;35746:19;9390:29;35786:14;;;9370:50;9439:12;;;24080:245::o;24332:416::-;24532:2;24546:47;;;9690:2;24517:18;;;35746:19;9726:34;35786:14;;;9706:55;-1:-1;;;9781:12;;;9774:32;9825:12;;;24503:245::o;24755:416::-;24955:2;24969:47;;;10076:2;24940:18;;;35746:19;10112:32;35786:14;;;10092:53;10164:12;;;24926:245::o;25178:416::-;25378:2;25392:47;;;25363:18;;;35746:19;10451:34;35786:14;;;10431:55;10505:12;;;25349:245::o;25601:416::-;25801:2;25815:47;;;10756:2;25786:18;;;35746:19;10792:31;35786:14;;;10772:52;10843:12;;;25772:245::o;26024:416::-;26224:2;26238:47;;;11094:2;26209:18;;;35746:19;11130:34;35786:14;;;11110:55;-1:-1;;;11185:12;;;11178:27;11224:12;;;26195:245::o;26447:416::-;26647:2;26661:47;;;11475:2;26632:18;;;35746:19;11511:32;35786:14;;;11491:53;11563:12;;;26618:245::o;26870:416::-;27070:2;27084:47;;;11814:2;27055:18;;;35746:19;11850:29;35786:14;;;11830:50;11899:12;;;27041:245::o;27293:416::-;27493:2;27507:47;;;12150:2;27478:18;;;35746:19;12186:28;35786:14;;;12166:49;12234:12;;;27464:245::o;27716:416::-;27916:2;27930:47;;;12485:2;27901:18;;;35746:19;-1:-1;;;35786:14;;;12501:42;12562:12;;;27887:245::o;28139:416::-;28339:2;28353:47;;;12813:1;28324:18;;;35746:19;-1:-1;;;35786:14;;;12828:32;12879:12;;;28310:245::o;28562:416::-;28762:2;28776:47;;;13130:2;28747:18;;;35746:19;13166:34;35786:14;;;13146:55;-1:-1;;;13221:12;;;13214:29;13262:12;;;28733:245::o;28985:416::-;29185:2;29199:47;;;13513:1;29170:18;;;35746:19;-1:-1;;;35786:14;;;13528:32;13579:12;;;29156:245::o;29408:416::-;29608:2;29622:47;;;13830:3;29593:18;;;35746:19;13867:34;35786:14;;;13847:55;13936:34;13922:12;;;13915:56;14005:34;13991:12;;;13984:56;-1:-1;;;14060:12;;;14053:29;14101:13;;;29579:245::o;29831:416::-;30031:2;30045:47;;;14353:2;30016:18;;;35746:19;14389:34;35786:14;;;14369:55;-1:-1;;;14444:12;;;14437:25;14481:12;;;30002:245::o;30254:416::-;30454:2;30468:47;;;14732:2;30439:18;;;35746:19;14768:30;35786:14;;;14748:51;14818:12;;;30425:245::o;30677:416::-;30877:2;30891:47;;;15069:2;30862:18;;;35746:19;-1:-1;;;35786:14;;;15085:38;15142:12;;;30848:245::o;31100:416::-;31300:2;31314:47;;;15393:2;31285:18;;;35746:19;-1:-1;;;35786:14;;;15409:39;15467:12;;;31271:245::o;31523:416::-;31723:2;31737:47;;;15718:2;31708:18;;;35746:19;15754:32;35786:14;;;15734:53;15806:12;;;31694:245::o;31946:416::-;32146:2;32160:47;;;31946:416;32131:18;;;35746:19;35786:14;;;32117:245::o;32369:416::-;32569:2;32583:47;;;16328:2;32554:18;;;35746:19;16364:25;35786:14;;;16344:46;16409:12;;;32540:245::o;32792:416::-;32992:2;33006:47;;;16660:2;32977:18;;;35746:19;16696:34;35786:14;;;16676:55;-1:-1;;;16751:12;;;16744:28;16791:12;;;32963:245::o;33215:416::-;33415:2;33429:47;;;17042:2;33400:18;;;35746:19;17078:33;35786:14;;;17058:54;17131:12;;;33386:245::o;33638:416::-;33838:2;33852:47;;;17382:2;33823:18;;;35746:19;-1:-1;;;35786:14;;;17398:41;17458:12;;;33809:245::o;34061:416::-;34261:2;34275:47;;;17709:2;34246:18;;;35746:19;-1:-1;;;35786:14;;;17725:38;17782:12;;;34232:245::o;34484:326::-;18087:23;;6644:37;;34663:2;34648:18;;34634:176::o;35046:333::-;6644:37;;;35365:2;35350:18;;6644:37;35201:2;35186:18;;35172:207::o;38051:268::-;38116:1;38123:101;38137:6;38134:1;38131:13;38123:101;;;38204:11;;;38198:18;38185:11;;;38178:39;38159:2;38152:10;38123:101;;;38239:6;38236:1;38233:13;38230:2;;;-1:-1;;38116:1;38286:16;;38279:27;38100:219::o;38432:117::-;-1:-1;;;;;36675:54;;38491:35;;38481:2;;38540:1;;38530:12;38556:111;38637:5;36303:13;36296:21;38615:5;38612:32;38602:2;;38658:1;;38648:12

Swarm Source

ipfs://66f0def471a66fd991c86eb45791a7529df0303974d4379bcd6adf339e00e6fb

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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