Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61018060 | 14391518 | 867 days ago | IN | 0 ETH | 0.14383612 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
14768385 | 808 days ago | 49.49008653 ETH | ||||
14768385 | 808 days ago | 49.47214808 ETH | ||||
14768385 | 808 days ago | 0.01793844 ETH | ||||
14727557 | 815 days ago | 4.39434328 ETH | ||||
14727557 | 815 days ago | 4.31607733 ETH | ||||
14671800 | 824 days ago | 0.07826594 ETH | ||||
14668971 | 824 days ago | 0.07522389 ETH | ||||
14594920 | 836 days ago | 2.87896546 ETH | ||||
14594920 | 836 days ago | 2.87896546 ETH | ||||
14570070 | 840 days ago | 3.74025178 ETH | ||||
14570070 | 840 days ago | 3.70387467 ETH | ||||
14544458 | 844 days ago | 0.03637711 ETH | ||||
14490430 | 852 days ago | 4.36014942 ETH | ||||
14490430 | 852 days ago | 4.33488164 ETH | ||||
14486520 | 853 days ago | 0.02526778 ETH | ||||
14486495 | 853 days ago | 0.02526604 ETH | ||||
14460948 | 857 days ago | 1.98861363 ETH | ||||
14460948 | 857 days ago | 1.98861363 ETH | ||||
14443853 | 859 days ago | 2.65823649 ETH | ||||
14443853 | 859 days ago | 2.64636951 ETH | ||||
14436819 | 860 days ago | 0.01118478 ETH | ||||
14436743 | 860 days ago | 0.00068218 ETH | ||||
14434192 | 861 days ago | 1.89340882 ETH | ||||
14434192 | 861 days ago | 1.89151636 ETH | ||||
14429734 | 861 days ago | 1.75127602 ETH |
Loading...
Loading
Contract Name:
BkdEthCvx
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-03-15 */ // SPDX-License-Identifier: GPL-3.0-or-later // Sources flattened with hardhat v2.6.1 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File @openzeppelin/contracts/utils/structs/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } } // File interfaces/IGasBank.sol pragma solidity 0.8.9; interface IGasBank { event Deposit(address indexed account, uint256 value); event Withdraw(address indexed account, address indexed receiver, uint256 value); function depositFor(address account) external payable; function withdrawUnused(address account) external; function withdrawFrom(address account, uint256 amount) external; function withdrawFrom( address account, address payable to, uint256 amount ) external; function balanceOf(address account) external view returns (uint256); } // File interfaces/IVaultReserve.sol pragma solidity 0.8.9; interface IVaultReserve { event Deposit(address indexed vault, address indexed token, uint256 amount); event Withdraw(address indexed vault, address indexed token, uint256 amount); event VaultListed(address indexed vault); function deposit(address token, uint256 amount) external payable returns (bool); function withdraw(address token, uint256 amount) external returns (bool); function getBalance(address vault, address token) external view returns (uint256); function canWithdraw(address vault) external view returns (bool); } // File interfaces/oracles/IOracleProvider.sol pragma solidity 0.8.9; interface IOracleProvider { /// @notice Quotes the USD price of `baseAsset` /// @param baseAsset the asset of which the price is to be quoted /// @return the USD price of the asset function getPriceUSD(address baseAsset) external view returns (uint256); /// @notice Quotes the ETH price of `baseAsset` /// @param baseAsset the asset of which the price is to be quoted /// @return the ETH price of the asset function getPriceETH(address baseAsset) external view returns (uint256); } // File interfaces/IPreparable.sol pragma solidity 0.8.9; interface IPreparable { event ConfigPreparedAddress(bytes32 indexed key, address value, uint256 delay); event ConfigPreparedNumber(bytes32 indexed key, uint256 value, uint256 delay); event ConfigUpdatedAddress(bytes32 indexed key, address oldValue, address newValue); event ConfigUpdatedNumber(bytes32 indexed key, uint256 oldValue, uint256 newValue); event ConfigReset(bytes32 indexed key); } // File interfaces/IStrategy.sol pragma solidity 0.8.9; interface IStrategy { function name() external view returns (string memory); function deposit() external payable returns (bool); function balance() external view returns (uint256); function withdraw(uint256 amount) external returns (bool); function withdrawAll() external returns (uint256); function harvestable() external view returns (uint256); function harvest() external returns (uint256); function strategist() external view returns (address); function shutdown() external returns (bool); function hasPendingFunds() external view returns (bool); } // File interfaces/IVault.sol pragma solidity 0.8.9; /** * @title Interface for a Vault */ interface IVault is IPreparable { event StrategyActivated(address indexed strategy); event StrategyDeactivated(address indexed strategy); /** * @dev 'netProfit' is the profit after all fees have been deducted */ event Harvest(uint256 indexed netProfit, uint256 indexed loss); function initialize( address _pool, uint256 _debtLimit, uint256 _targetAllocation, uint256 _bound ) external; function withdrawFromStrategyWaitingForRemoval(address strategy) external returns (uint256); function deposit() external payable; function withdraw(uint256 amount) external returns (bool); function initializeStrategy(address strategy_) external returns (bool); function withdrawAll() external; function withdrawFromReserve(uint256 amount) external; function getStrategy() external view returns (IStrategy); function getStrategiesWaitingForRemoval() external view returns (address[] memory); function getAllocatedToStrategyWaitingForRemoval(address strategy) external view returns (uint256); function getTotalUnderlying() external view returns (uint256); function getUnderlying() external view returns (address); } // File interfaces/pool/ILiquidityPool.sol pragma solidity 0.8.9; interface ILiquidityPool is IPreparable { event Deposit(address indexed minter, uint256 depositAmount, uint256 mintedLpTokens); event DepositFor( address indexed minter, address indexed mintee, uint256 depositAmount, uint256 mintedLpTokens ); event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens); event LpTokenSet(address indexed lpToken); event StakerVaultSet(address indexed stakerVault); function redeem(uint256 redeemTokens) external returns (uint256); function redeem(uint256 redeemTokens, uint256 minRedeemAmount) external returns (uint256); function calcRedeem(address account, uint256 underlyingAmount) external returns (uint256); function deposit(uint256 mintAmount) external payable returns (uint256); function deposit(uint256 mintAmount, uint256 minTokenAmount) external payable returns (uint256); function depositAndStake(uint256 depositAmount, uint256 minTokenAmount) external payable returns (uint256); function depositFor(address account, uint256 depositAmount) external payable returns (uint256); function depositFor( address account, uint256 depositAmount, uint256 minTokenAmount ) external payable returns (uint256); function unstakeAndRedeem(uint256 redeemLpTokens, uint256 minRedeemAmount) external returns (uint256); function handleLpTokenTransfer( address from, address to, uint256 amount ) external; function executeNewVault() external returns (address); function executeNewMaxWithdrawalFee() external returns (uint256); function executeNewRequiredReserves() external returns (uint256); function executeNewReserveDeviation() external returns (uint256); function setLpToken(address _lpToken) external returns (bool); function setStaker() external returns (bool); function isCapped() external returns (bool); function uncap() external returns (bool); function updateDepositCap(uint256 _depositCap) external returns (bool); function getUnderlying() external view returns (address); function getLpToken() external view returns (address); function getWithdrawalFee(address account, uint256 amount) external view returns (uint256); function getVault() external view returns (IVault); function exchangeRate() external view returns (uint256); } // File libraries/AddressProviderMeta.sol pragma solidity 0.8.9; library AddressProviderMeta { struct Meta { bool freezable; bool frozen; } function fromUInt(uint256 value) internal pure returns (Meta memory) { Meta memory meta; meta.freezable = (value & 1) == 1; meta.frozen = ((value >> 1) & 1) == 1; return meta; } function toUInt(Meta memory meta) internal pure returns (uint256) { uint256 value; value |= meta.freezable ? 1 : 0; value |= meta.frozen ? 1 << 1 : 0; return value; } } // File interfaces/IAddressProvider.sol pragma solidity 0.8.9; // solhint-disable ordering interface IAddressProvider is IPreparable { event KnownAddressKeyAdded(bytes32 indexed key); event StakerVaultListed(address indexed stakerVault); event StakerVaultDelisted(address indexed stakerVault); event ActionListed(address indexed action); event PoolListed(address indexed pool); event PoolDelisted(address indexed pool); event VaultUpdated(address indexed previousVault, address indexed newVault); /** Key functions */ function getKnownAddressKeys() external view returns (bytes32[] memory); function freezeAddress(bytes32 key) external; /** Pool functions */ function allPools() external view returns (address[] memory); function addPool(address pool) external; function poolsCount() external view returns (uint256); function getPoolAtIndex(uint256 index) external view returns (address); function isPool(address pool) external view returns (bool); function removePool(address pool) external returns (bool); function getPoolForToken(address token) external view returns (ILiquidityPool); function safeGetPoolForToken(address token) external view returns (address); /** Vault functions */ function updateVault(address previousVault, address newVault) external; function allVaults() external view returns (address[] memory); function vaultsCount() external view returns (uint256); function getVaultAtIndex(uint256 index) external view returns (address); function isVault(address vault) external view returns (bool); /** Action functions */ function allActions() external view returns (address[] memory); function addAction(address action) external returns (bool); function isAction(address action) external view returns (bool); /** Address functions */ function initializeAddress( bytes32 key, address initialAddress, bool frezable ) external; function initializeAndFreezeAddress(bytes32 key, address initialAddress) external; function getAddress(bytes32 key) external view returns (address); function getAddress(bytes32 key, bool checkExists) external view returns (address); function getAddressMeta(bytes32 key) external view returns (AddressProviderMeta.Meta memory); function prepareAddress(bytes32 key, address newAddress) external returns (bool); function executeAddress(bytes32 key) external returns (address); function resetAddress(bytes32 key) external returns (bool); /** Staker vault functions */ function allStakerVaults() external view returns (address[] memory); function tryGetStakerVault(address token) external view returns (bool, address); function getStakerVault(address token) external view returns (address); function addStakerVault(address stakerVault) external returns (bool); function isStakerVault(address stakerVault, address token) external view returns (bool); function isStakerVaultRegistered(address stakerVault) external view returns (bool); function isWhiteListedFeeHandler(address feeHandler) external view returns (bool); } // File interfaces/IRoleManager.sol pragma solidity 0.8.9; interface IRoleManager { event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); function grantRole(bytes32 role, address account) external; function revokeRole(bytes32 role, address account) external; function hasRole(bytes32 role, address account) external view returns (bool); function hasAnyRole(bytes32[] memory roles, address account) external view returns (bool); function hasAnyRole( bytes32 role1, bytes32 role2, address account ) external view returns (bool); function hasAnyRole( bytes32 role1, bytes32 role2, bytes32 role3, address account ) external view returns (bool); function getRoleMemberCount(bytes32 role) external view returns (uint256); function getRoleMember(bytes32 role, uint256 index) external view returns (address); } // File interfaces/tokenomics/IBkdToken.sol pragma solidity 0.8.9; interface IBkdToken is IERC20 { function mint(address account, uint256 amount) external; } // File interfaces/tokenomics/IInflationManager.sol pragma solidity 0.8.9; interface IInflationManager { event KeeperGaugeListed(address indexed pool, address indexed keeperGauge); event AmmGaugeListed(address indexed token, address indexed ammGauge); event KeeperGaugeDelisted(address indexed pool, address indexed keeperGauge); event AmmGaugeDelisted(address indexed token, address indexed ammGauge); /** Pool functions */ function setKeeperGauge(address pool, address _keeperGauge) external returns (bool); function setAmmGauge(address token, address _ammGauge) external returns (bool); function getAllAmmGauges() external view returns (address[] memory); function getLpRateForStakerVault(address stakerVault) external view returns (uint256); function getKeeperRateForPool(address pool) external view returns (uint256); function getAmmRateForToken(address token) external view returns (uint256); function getKeeperWeightForPool(address pool) external view returns (uint256); function getAmmWeightForToken(address pool) external view returns (uint256); function getLpPoolWeight(address pool) external view returns (uint256); function getKeeperGaugeForPool(address pool) external view returns (address); function getAmmGaugeForToken(address token) external view returns (address); function isInflationWeightManager(address account) external view returns (bool); function removeStakerVaultFromInflation(address stakerVault, address lpToken) external; function addGaugeForVault(address lpToken) external returns (bool); function whitelistGauge(address gauge) external; function checkpointAllGauges() external returns (bool); function mintRewards(address beneficiary, uint256 amount) external; function addStrategyToDepositStakerVault(address depositStakerVault, address strategyPool) external returns (bool); /** Weight setter functions **/ function prepareLpPoolWeight(address lpToken, uint256 newPoolWeight) external returns (bool); function prepareAmmTokenWeight(address token, uint256 newTokenWeight) external returns (bool); function prepareKeeperPoolWeight(address pool, uint256 newPoolWeight) external returns (bool); function executeLpPoolWeight(address lpToken) external returns (uint256); function executeAmmTokenWeight(address token) external returns (uint256); function executeKeeperPoolWeight(address pool) external returns (uint256); function batchPrepareLpPoolWeights(address[] calldata lpTokens, uint256[] calldata weights) external returns (bool); function batchPrepareAmmTokenWeights(address[] calldata tokens, uint256[] calldata weights) external returns (bool); function batchPrepareKeeperPoolWeights(address[] calldata pools, uint256[] calldata weights) external returns (bool); function batchExecuteLpPoolWeights(address[] calldata lpTokens) external returns (bool); function batchExecuteAmmTokenWeights(address[] calldata tokens) external returns (bool); function batchExecuteKeeperPoolWeights(address[] calldata pools) external returns (bool); } // File interfaces/IController.sol pragma solidity 0.8.9; // solhint-disable ordering interface IController is IPreparable { function addressProvider() external view returns (IAddressProvider); function inflationManager() external view returns (IInflationManager); function addStakerVault(address stakerVault) external returns (bool); function removePool(address pool) external returns (bool); /** Keeper functions */ function prepareKeeperRequiredStakedBKD(uint256 amount) external; function executeKeeperRequiredStakedBKD() external; function getKeeperRequiredStakedBKD() external view returns (uint256); function canKeeperExecuteAction(address keeper) external view returns (bool); /** Miscellaneous functions */ function getTotalEthRequiredForGas(address payer) external view returns (uint256); } // File libraries/AddressProviderKeys.sol pragma solidity 0.8.9; library AddressProviderKeys { bytes32 internal constant _TREASURY_KEY = "treasury"; bytes32 internal constant _GAS_BANK_KEY = "gasBank"; bytes32 internal constant _VAULT_RESERVE_KEY = "vaultReserve"; bytes32 internal constant _SWAPPER_REGISTRY_KEY = "swapperRegistry"; bytes32 internal constant _ORACLE_PROVIDER_KEY = "oracleProvider"; bytes32 internal constant _POOL_FACTORY_KEY = "poolFactory"; bytes32 internal constant _CONTROLLER_KEY = "controller"; bytes32 internal constant _BKD_LOCKER_KEY = "bkdLocker"; bytes32 internal constant _ROLE_MANAGER_KEY = "roleManager"; } // File libraries/AddressProviderHelpers.sol pragma solidity 0.8.9; library AddressProviderHelpers { /** * @return The address of the treasury. */ function getTreasury(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._TREASURY_KEY); } /** * @return The gas bank. */ function getGasBank(IAddressProvider provider) internal view returns (IGasBank) { return IGasBank(provider.getAddress(AddressProviderKeys._GAS_BANK_KEY)); } /** * @return The address of the vault reserve. */ function getVaultReserve(IAddressProvider provider) internal view returns (IVaultReserve) { return IVaultReserve(provider.getAddress(AddressProviderKeys._VAULT_RESERVE_KEY)); } /** * @return The address of the swapperRegistry. */ function getSwapperRegistry(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._SWAPPER_REGISTRY_KEY); } /** * @return The oracleProvider. */ function getOracleProvider(IAddressProvider provider) internal view returns (IOracleProvider) { return IOracleProvider(provider.getAddress(AddressProviderKeys._ORACLE_PROVIDER_KEY)); } /** * @return the address of the BKD locker */ function getBKDLocker(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._BKD_LOCKER_KEY); } /** * @return the address of the BKD locker */ function getRoleManager(IAddressProvider provider) internal view returns (IRoleManager) { return IRoleManager(provider.getAddress(AddressProviderKeys._ROLE_MANAGER_KEY)); } /** * @return the controller */ function getController(IAddressProvider provider) internal view returns (IController) { return IController(provider.getAddress(AddressProviderKeys._CONTROLLER_KEY)); } } // File libraries/ScaledMath.sol pragma solidity 0.8.9; /* * @dev To use functions of this contract, at least one of the numbers must * be scaled to `DECIMAL_SCALE`. The result will scaled to `DECIMAL_SCALE` * if both numbers are scaled to `DECIMAL_SCALE`, otherwise to the scale * of the number not scaled by `DECIMAL_SCALE` */ library ScaledMath { // solhint-disable-next-line private-vars-leading-underscore uint256 internal constant DECIMAL_SCALE = 1e18; // solhint-disable-next-line private-vars-leading-underscore uint256 internal constant ONE = 1e18; /** * @notice Performs a multiplication between two scaled numbers */ function scaledMul(uint256 a, uint256 b) internal pure returns (uint256) { return (a * b) / DECIMAL_SCALE; } /** * @notice Performs a division between two scaled numbers */ function scaledDiv(uint256 a, uint256 b) internal pure returns (uint256) { return (a * DECIMAL_SCALE) / b; } /** * @notice Performs a division between two numbers, rounding up the result */ function scaledDivRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { return (a * DECIMAL_SCALE + b - 1) / b; } /** * @notice Performs a division between two numbers, ignoring any scaling and rounding up the result */ function divRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { return (a + b - 1) / b; } } // File contracts/utils/CvxMintAmount.sol pragma solidity 0.8.9; abstract contract CvxMintAmount { uint256 private constant _CLIFF_SIZE = 100000 * 1e18; //new cliff every 100,000 tokens uint256 private constant _CLIFF_COUNT = 1000; // 1,000 cliffs uint256 private constant _MAX_SUPPLY = 100000000 * 1e18; //100 mil max supply IERC20 private constant _CVX_TOKEN = IERC20(address(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B)); // CVX Token function getCvxMintAmount(uint256 crvEarned) public view returns (uint256) { //first get total supply uint256 cvxTotalSupply = _CVX_TOKEN.totalSupply(); //get current cliff uint256 currentCliff = cvxTotalSupply / _CLIFF_SIZE; //if current cliff is under the max if (currentCliff >= _CLIFF_COUNT) return 0; //get remaining cliffs uint256 remaining = _CLIFF_COUNT - currentCliff; //multiply ratio of remaining cliffs to total cliffs against amount CRV received uint256 cvxEarned = (crvEarned * remaining) / _CLIFF_COUNT; //double check we have not gone over the max supply uint256 amountTillMax = _MAX_SUPPLY - cvxTotalSupply; if (cvxEarned > amountTillMax) cvxEarned = amountTillMax; return cvxEarned; } } // File libraries/Errors.sol pragma solidity 0.8.9; // solhint-disable private-vars-leading-underscore library Error { string internal constant ADDRESS_WHITELISTED = "address already whitelisted"; string internal constant ADMIN_ALREADY_SET = "admin has already been set once"; string internal constant ADDRESS_NOT_WHITELISTED = "address not whitelisted"; string internal constant ADDRESS_NOT_FOUND = "address not found"; string internal constant CONTRACT_INITIALIZED = "contract can only be initialized once"; string internal constant CONTRACT_PAUSED = "contract is paused"; string internal constant INVALID_AMOUNT = "invalid amount"; string internal constant INVALID_INDEX = "invalid index"; string internal constant INVALID_VALUE = "invalid msg.value"; string internal constant INVALID_SENDER = "invalid msg.sender"; string internal constant INVALID_TOKEN = "token address does not match pool's LP token address"; string internal constant INVALID_DECIMALS = "incorrect number of decimals"; string internal constant INVALID_ARGUMENT = "invalid argument"; string internal constant INVALID_PARAMETER_VALUE = "invalid parameter value attempted"; string internal constant INVALID_IMPLEMENTATION = "invalid pool implementation for given coin"; string internal constant INVALID_POOL_IMPLEMENTATION = "invalid pool implementation for given coin"; string internal constant INVALID_LP_TOKEN_IMPLEMENTATION = "invalid LP Token implementation for given coin"; string internal constant INVALID_VAULT_IMPLEMENTATION = "invalid vault implementation for given coin"; string internal constant INVALID_STAKER_VAULT_IMPLEMENTATION = "invalid stakerVault implementation for given coin"; string internal constant INSUFFICIENT_BALANCE = "insufficient balance"; string internal constant ADDRESS_ALREADY_SET = "Address is already set"; string internal constant INSUFFICIENT_STRATEGY_BALANCE = "insufficient strategy balance"; string internal constant INSUFFICIENT_FUNDS_RECEIVED = "insufficient funds received"; string internal constant ADDRESS_DOES_NOT_EXIST = "address does not exist"; string internal constant ADDRESS_FROZEN = "address is frozen"; string internal constant ROLE_EXISTS = "role already exists"; string internal constant CANNOT_REVOKE_ROLE = "cannot revoke role"; string internal constant UNAUTHORIZED_ACCESS = "unauthorized access"; string internal constant SAME_ADDRESS_NOT_ALLOWED = "same address not allowed"; string internal constant SELF_TRANSFER_NOT_ALLOWED = "self-transfer not allowed"; string internal constant ZERO_ADDRESS_NOT_ALLOWED = "zero address not allowed"; string internal constant ZERO_TRANSFER_NOT_ALLOWED = "zero transfer not allowed"; string internal constant THRESHOLD_TOO_HIGH = "threshold is too high, must be under 10"; string internal constant INSUFFICIENT_THRESHOLD = "insufficient threshold"; string internal constant NO_POSITION_EXISTS = "no position exists"; string internal constant POSITION_ALREADY_EXISTS = "position already exists"; string internal constant PROTOCOL_NOT_FOUND = "protocol not found"; string internal constant TOP_UP_FAILED = "top up failed"; string internal constant SWAP_PATH_NOT_FOUND = "swap path not found"; string internal constant UNDERLYING_NOT_SUPPORTED = "underlying token not supported"; string internal constant NOT_ENOUGH_FUNDS_WITHDRAWN = "not enough funds were withdrawn from the pool"; string internal constant FAILED_TRANSFER = "transfer failed"; string internal constant FAILED_MINT = "mint failed"; string internal constant FAILED_REPAY_BORROW = "repay borrow failed"; string internal constant FAILED_METHOD_CALL = "method call failed"; string internal constant NOTHING_TO_CLAIM = "there is no claimable balance"; string internal constant ERC20_BALANCE_EXCEEDED = "ERC20: transfer amount exceeds balance"; string internal constant INVALID_MINTER = "the minter address of the LP token and the pool address do not match"; string internal constant STAKER_VAULT_EXISTS = "a staker vault already exists for the token"; string internal constant DEADLINE_NOT_ZERO = "deadline must be 0"; string internal constant DEADLINE_NOT_SET = "deadline is 0"; string internal constant DEADLINE_NOT_REACHED = "deadline has not been reached yet"; string internal constant DELAY_TOO_SHORT = "delay be at least 3 days"; string internal constant INSUFFICIENT_UPDATE_BALANCE = "insufficient funds for updating the position"; string internal constant SAME_AS_CURRENT = "value must be different to existing value"; string internal constant NOT_CAPPED = "the pool is not currently capped"; string internal constant ALREADY_CAPPED = "the pool is already capped"; string internal constant EXCEEDS_DEPOSIT_CAP = "deposit exceeds deposit cap"; string internal constant VALUE_TOO_LOW_FOR_GAS = "value too low to cover gas"; string internal constant NOT_ENOUGH_FUNDS = "not enough funds to withdraw"; string internal constant ESTIMATED_GAS_TOO_HIGH = "too much ETH will be used for gas"; string internal constant DEPOSIT_FAILED = "deposit failed"; string internal constant GAS_TOO_HIGH = "too much ETH used for gas"; string internal constant GAS_BANK_BALANCE_TOO_LOW = "not enough ETH in gas bank to cover gas"; string internal constant INVALID_TOKEN_TO_ADD = "Invalid token to add"; string internal constant INVALID_TOKEN_TO_REMOVE = "token can not be removed"; string internal constant TIME_DELAY_NOT_EXPIRED = "time delay not expired yet"; string internal constant UNDERLYING_NOT_WITHDRAWABLE = "pool does not support additional underlying coins to be withdrawn"; string internal constant STRATEGY_SHUT_DOWN = "Strategy is shut down"; string internal constant STRATEGY_DOES_NOT_EXIST = "Strategy does not exist"; string internal constant UNSUPPORTED_UNDERLYING = "Underlying not supported"; string internal constant NO_DEX_SET = "no dex has been set for token"; string internal constant INVALID_TOKEN_PAIR = "invalid token pair"; string internal constant TOKEN_NOT_USABLE = "token not usable for the specific action"; string internal constant ADDRESS_NOT_ACTION = "address is not registered action"; string internal constant INVALID_SLIPPAGE_TOLERANCE = "Invalid slippage tolerance"; string internal constant POOL_NOT_PAUSED = "Pool must be paused to withdraw from reserve"; string internal constant INTERACTION_LIMIT = "Max of one deposit and withdraw per block"; string internal constant GAUGE_EXISTS = "Gauge already exists"; string internal constant GAUGE_DOES_NOT_EXIST = "Gauge does not exist"; string internal constant EXCEEDS_MAX_BOOST = "Not allowed to exceed maximum boost on Convex"; string internal constant PREPARED_WITHDRAWAL = "Cannot relock funds when withdrawal is being prepared"; string internal constant ASSET_NOT_SUPPORTED = "Asset not supported"; string internal constant STALE_PRICE = "Price is stale"; string internal constant NEGATIVE_PRICE = "Price is negative"; string internal constant NOT_ENOUGH_BKD_STAKED = "Not enough BKD tokens staked"; string internal constant RESERVE_ACCESS_EXCEEDED = "Reserve access exceeded"; } // File libraries/Roles.sol pragma solidity 0.8.9; // solhint-disable private-vars-leading-underscore library Roles { bytes32 internal constant GOVERNANCE = "governance"; bytes32 internal constant ADDRESS_PROVIDER = "address_provider"; bytes32 internal constant POOL_FACTORY = "pool_factory"; bytes32 internal constant CONTROLLER = "controller"; bytes32 internal constant GAUGE_ZAP = "gauge_zap"; bytes32 internal constant MAINTENANCE = "maintenance"; bytes32 internal constant INFLATION_MANAGER = "inflation_manager"; bytes32 internal constant POOL = "pool"; bytes32 internal constant VAULT = "vault"; } // File contracts/access/AuthorizationBase.sol pragma solidity 0.8.9; /** * @notice Provides modifiers for authorization */ abstract contract AuthorizationBase { /** * @notice Only allows a sender with `role` to perform the given action */ modifier onlyRole(bytes32 role) { require(_roleManager().hasRole(role, msg.sender), Error.UNAUTHORIZED_ACCESS); _; } /** * @notice Only allows a sender with GOVERNANCE role to perform the given action */ modifier onlyGovernance() { require(_roleManager().hasRole(Roles.GOVERNANCE, msg.sender), Error.UNAUTHORIZED_ACCESS); _; } /** * @notice Only allows a sender with any of `roles` to perform the given action */ modifier onlyRoles2(bytes32 role1, bytes32 role2) { require(_roleManager().hasAnyRole(role1, role2, msg.sender), Error.UNAUTHORIZED_ACCESS); _; } /** * @notice Only allows a sender with any of `roles` to perform the given action */ modifier onlyRoles3( bytes32 role1, bytes32 role2, bytes32 role3 ) { require( _roleManager().hasAnyRole(role1, role2, role3, msg.sender), Error.UNAUTHORIZED_ACCESS ); _; } function roleManager() external view virtual returns (IRoleManager) { return _roleManager(); } function _roleManager() internal view virtual returns (IRoleManager); } // File contracts/access/Authorization.sol pragma solidity 0.8.9; contract Authorization is AuthorizationBase { IRoleManager internal immutable __roleManager; constructor(IRoleManager roleManager) { __roleManager = roleManager; } function _roleManager() internal view override returns (IRoleManager) { return __roleManager; } } // File contracts/utils/SlippageTolerance.sol pragma solidity 0.8.9; contract SlippageTolerance is Authorization { using ScaledMath for uint256; uint256 public slippageTolerance; event SetSlippageTolerance(uint256 value); // Emitted after a succuessful setting of slippage tolerance constructor(IRoleManager roleManager) Authorization(roleManager) { slippageTolerance = 0.97e18; } /** * @notice Set slippage tolerance for reward token swaps. * @dev Stored as a multiplier, e.g. 2% would be set as 0.98. * @param _slippageTolerance New imbalance tolarance out. * @return True if successfully set. */ function setSlippageTolerance(uint256 _slippageTolerance) external onlyGovernance returns (bool) { require(_slippageTolerance <= ScaledMath.ONE, Error.INVALID_SLIPPAGE_TOLERANCE); require(_slippageTolerance > 0.8e18, Error.INVALID_SLIPPAGE_TOLERANCE); slippageTolerance = _slippageTolerance; emit SetSlippageTolerance(_slippageTolerance); return true; } } // File interfaces/vendor/IBooster.sol pragma solidity 0.8.9; interface IBooster { function poolInfo(uint256 pid) external returns ( address lpToken, address token, address gauge, address crvRewards, address stash, bool shutdown ); /** * @dev `_pid` is the ID of the Convex for a specific Curve LP token. */ function deposit( uint256 _pid, uint256 _amount, bool _stake ) external returns (bool); function withdraw(uint256 _pid, uint256 _amount) external returns (bool); function withdrawAll(uint256 _pid) external returns (bool); function depositAll(uint256 _pid, bool _stake) external returns (bool); } // File interfaces/vendor/ICurveSwapEth.sol pragma solidity 0.8.9; interface ICurveSwapEth { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[2] calldata amounts, uint256 min_mint_amount) external payable; function remove_liquidity_imbalance(uint256[3] calldata amounts, uint256 max_burn_amount) external; function remove_liquidity_imbalance(uint256[2] calldata amounts, uint256 max_burn_amount) external; function remove_liquidity(uint256 _amount, uint256[3] calldata min_amounts) external; function exchange( uint256 i, uint256 j, uint256 dx, uint256 min_dy ) external payable; function coins(uint256 i) external view returns (address); function get_dy( uint256 i, uint256 j, uint256 dx ) external view returns (uint256); function calc_token_amount(uint256[3] calldata amounts, bool deposit) external view returns (uint256); function calc_token_amount(uint256[2] calldata amounts, bool deposit) external view returns (uint256); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_amount ) external; } // File interfaces/vendor/IRewardStaking.sol pragma solidity 0.8.9; interface IRewardStaking { function stakeFor(address, uint256) external; function stake(uint256) external; function stakeAll() external returns (bool); function withdraw(uint256 amount, bool claim) external returns (bool); function withdrawAndUnwrap(uint256 amount, bool claim) external returns (bool); function earned(address account) external view returns (uint256); function getReward() external; function getReward(address _account, bool _claimExtras) external; function extraRewardsLength() external view returns (uint256); function extraRewards(uint256 _pid) external view returns (address); function rewardToken() external view returns (address); function balanceOf(address account) external view returns (uint256); } // File interfaces/vendor/UniswapRouter02.sol pragma solidity 0.8.9; interface UniswapRouter02 { function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external returns (uint256 amountIn); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external view returns (uint256 amountOut); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsOut(uint256 amountIn, address[] memory path) external view returns (uint256[] memory amounts); function getReserves( address factory, address tokenA, address tokenB ) external view returns (uint256 reserveA, uint256 reserveB); function WETH() external pure returns (address); } interface UniswapV2Pair { function getReserves() external view returns ( uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast ); } interface UniswapV2Factory { function getPair(address tokenA, address tokenB) external view returns (address pair); } // File interfaces/vendor/IWETH.sol pragma solidity 0.8.9; /** * @notice Interface for WETH9 * @dev https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code */ interface IWETH is IERC20 { function deposit() external payable; function withdraw(uint256 wad) external; } // File contracts/strategies/BkdEthCvx.sol pragma solidity 0.8.9; /** * This is the BkdEthCvx strategy, which is designed to be used by a Backd ETH Vault. * The strategy holds ETH as it's underlying and allocates liquidity to Convex via given Curve Pool with 2 underlying tokens. * Rewards received on Convex (CVX, CRV), are sold in part for the underlying. * A share of earned CVX & CRV are retained on behalf of the Backd community to participate in governance. */ contract BkdEthCvx is IStrategy, CvxMintAmount, SlippageTolerance { using ScaledMath for uint256; using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; using AddressProviderHelpers for IAddressProvider; uint256 private constant _CURVE_CVX_INDEX = 1; uint256 private constant _CURVE_ETH_INDEX = 0; IBooster private constant _BOOSTER = IBooster(0xF403C135812408BFbE8713b5A23a04b3D48AAE31); // Convex Booster Contract IERC20 private constant _CVX = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); // CVX IWETH private constant _WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); // WETH IERC20 private constant _CRV = IERC20(0xD533a949740bb3306d119CC777fa900bA034cd52); // CRV UniswapRouter02 private constant _SUSHISWAP = UniswapRouter02(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); // Sushiswap Router for swaps UniswapRouter02 private constant _UNISWAP = UniswapRouter02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); // Uniswap Router for swaps ICurveSwapEth internal constant _CVX_ETH_CURVE_POOL = ICurveSwapEth(0xB576491F1E6e5E62f1d8F26062Ee822B40B0E0d4); // CVX/ETH Curve Pool IAddressProvider internal immutable _addressProvider; // Address provider used for getting oracle provider address payable public immutable vault; // Backd Vault ICurveSwapEth public immutable curvePool; // Curve Pool IERC20 public immutable lp; // Curve Pool LP Token IRewardStaking public immutable rewards; // Rewards Contract for claiming Convex Rewards uint256 public immutable convexPid; // Index of Convex Pool in Booster Contract uint256 public immutable curveIndex; // Underlying index in Curve Pool uint256 public imbalanceToleranceIn; // Maximum allowed slippage from Curve Pool Imbalance for depositing uint256 public imbalanceToleranceOut; // Maximum allowed slippage from Curve Pool Imbalance for withdrawing address public communityReserve; // Address for sending CVX & CRV Community Reserve share uint256 public cvxCommunityReserveShare; // Share of CVX sent to Community Reserve uint256 public crvCommunityReserveShare; // Share of CRV sent to Community Reserve address public override strategist; // The strategist for the strategy bool public isShutdown; // If the strategy is shutdown, stops all deposits mapping(address => UniswapRouter02) public tokenDex; // Dex to use for swapping for a given token EnumerableSet.AddressSet private _rewardTokens; // List of additional reward tokens when claiming rewards on Convex event Deposit(uint256 amount); // Emitted after a successfull deposit event Withdraw(uint256 amount); // Emitted after a successful withdrawal event WithdrawAll(uint256 amount); // Emitted after successfully withdrwaing all event Harvest(uint256 amount); // Emitted after a successful harvest event Shutdown(); // Emitted after a successful shutdown event SetCommunityReserve(address reserve); // Emitted after a succuessful setting of reserve event SetCrvCommunityReserveShare(uint256 value); // Emitted after a succuessful setting of CRV Community Reserve Share event SetCvxCommunityReserveShare(uint256 value); // Emitted after a succuessful setting of CVX Community Reserve Share event SetImbalanceToleranceIn(uint256 value); // Emitted after a succuessful setting of imbalance tolerance in event SetImbalanceToleranceOut(uint256 value); // Emitted after a succuessful setting of imbalance tolerance out event SetStrategist(address strategist); // Emitted after a succuessful setting of strategist event AddRewardToken(address token); // Emitted after successfully adding a new reward token event RemoveRewardToken(address token); // Emitted after successfully removing a reward token event SwapDex(address token, address newDex); // Emitted after successfully swapping a tokens dex modifier onlyVault() { require(msg.sender == vault, Error.UNAUTHORIZED_ACCESS); _; } constructor( address vault_, address strategist_, address curvePool_, uint256 convexPid_, uint256 curveIndex_, IAddressProvider addressProvider_ ) SlippageTolerance(addressProvider_.getRoleManager()) { // Setting inputs vault = payable(vault_); strategist = strategist_; curvePool = ICurveSwapEth(curvePool_); convexPid = convexPid_; curveIndex = curveIndex_; _addressProvider = addressProvider_; // Setting LP and Rewards contracts (address lp_, , , address rewards_, , ) = _BOOSTER.poolInfo(convexPid_); lp = IERC20(lp_); rewards = IRewardStaking(rewards_); // Setting default values imbalanceToleranceIn = 0.0007e18; imbalanceToleranceOut = 0.0104e18; // Setting dexes _setDex(address(_CRV), _SUSHISWAP); _setDex(address(_CVX), _SUSHISWAP); // Approvals IERC20(lp_).safeApprove(address(_BOOSTER), type(uint256).max); _CVX.safeApprove(address(_CVX_ETH_CURVE_POOL), type(uint256).max); _CRV.safeApprove(address(_SUSHISWAP), type(uint256).max); } receive() external payable {} /** * @notice Deposit all available underlying into Convex pool. * @dev Liquidity is added to Curve Pool then Curve LP tokens are deposited * into Convex and Convex LP tokens are staked for rewards by default. * @return True if successful deposit. */ function deposit() external payable override onlyVault returns (bool) { require(!isShutdown, Error.STRATEGY_SHUT_DOWN); // Depositing into Curve Pool uint256 underlyingBalance = _underlyingBalance(); if (underlyingBalance == 0) return false; uint256[2] memory amounts; amounts[curveIndex] = underlyingBalance; curvePool.add_liquidity{value: underlyingBalance}( amounts, _minLpAccepted(underlyingBalance) ); // Depositing into Convex and Staking if (!_BOOSTER.depositAll(convexPid, true)) return false; emit Deposit(underlyingBalance); return true; } /** * @notice Withdraw an amount of underlying to the vault. * @dev This can only be called by the vault. * If the amount is not available, it will be made liquid. * @param amount Amount of underlying to withdraw. * @return True if successful withdrawal. */ function withdraw(uint256 amount) external override onlyVault returns (bool) { if (amount == 0) return false; uint256 underlyingBalance = _underlyingBalance(); // Transferring from idle balance if enough if (underlyingBalance >= amount) { if (!vault.send(amount)) return false; emit Withdraw(amount); return true; } // Unstaking needed LP Tokens from Convex uint256 requiredUnderlyingAmount = amount - underlyingBalance; uint256 maxLpBurned = _maxLpBurned(requiredUnderlyingAmount); uint256 requiredLpAmount = maxLpBurned - _lpBalance(); if (!rewards.withdrawAndUnwrap(requiredLpAmount, false)) return false; // Removing needed liquidity from Curve uint256[2] memory amounts; // solhint-disable-next-line reentrancy amounts[curveIndex] = requiredUnderlyingAmount; curvePool.remove_liquidity_imbalance(amounts, maxLpBurned); vault.transfer(amount); emit Withdraw(amount); return true; } /** * @notice Withdraw all underlying to vault. * @dev This does not liquidate reward tokens and only considers * idle underlying, idle lp tokens and staked lp tokens. * @return Amount of underlying withdrawn */ function withdrawAll() external override returns (uint256) { require( msg.sender == vault || _roleManager().hasRole(Roles.GOVERNANCE, msg.sender), Error.UNAUTHORIZED_ACCESS ); // Unstaking and withdrawing from Convex pool uint256 stakedBalance = _stakedBalance(); if (stakedBalance > 0) { if (!rewards.withdrawAndUnwrap(stakedBalance, false)) return 0; } // Removing liquidity from Curve uint256 lpBalance = _lpBalance(); if (lpBalance > 0) { curvePool.remove_liquidity_one_coin( lpBalance, int128(uint128(curveIndex)), _minUnderlyingAccepted(lpBalance) ); } // Transferring underlying to vault uint256 underlyingBalance = _underlyingBalance(); if (underlyingBalance == 0) return 0; vault.transfer(underlyingBalance); emit WithdrawAll(underlyingBalance); return underlyingBalance; } /** * @notice Harvests reward tokens and sells these for the underlying. * @dev Any underlying harvested is not redeposited by this method. * @return Amount of underlying harvested. */ function harvest() external override onlyVault returns (uint256) { uint256 underlyingBalance = _underlyingBalance(); // Claim Convex rewards rewards.getReward(address(this), false); // Sending share to Community Reserve _sendCommunityReserveShare(); // Swap CVX for WETH _swapAllForWeth(_CVX); // Swap CRV for WETH _swapAllForWeth(_CRV); // Swap Extra Rewards for WETH for (uint256 i = 0; i < _rewardTokens.length(); i++) { _swapAllForWeth(IERC20(_rewardTokens.at(i))); } // Swap WETH for underlying _swapWethForUnderlying(); uint256 harvested = _underlyingBalance() - underlyingBalance; emit Harvest(harvested); return harvested; } /** * @notice Shuts down the strategy, disabling deposits. * @return True if the strategy was succesfully shutdown */ function shutdown() external override onlyVault returns (bool) { if (isShutdown) return false; isShutdown = true; emit Shutdown(); return true; } /** * @notice Set the address of the communit reserve. * @dev CRV & CVX will be taxed and allocated to the reserve, * such that Backd can participate in governance. * @param _communityReserve Address of the community reserve. * @return True if successfully set. */ function setCommunityReserve(address _communityReserve) external onlyGovernance returns (bool) { communityReserve = _communityReserve; emit SetCommunityReserve(_communityReserve); return true; } /** * @notice Set the share of CRV to send to the Community Reserve. * @param crvCommunityReserveShare_ New fee charged on CRV rewards for governance. * @return True if successfully set. */ function setCrvCommunityReserveShare(uint256 crvCommunityReserveShare_) external onlyGovernance returns (bool) { require(crvCommunityReserveShare_ <= ScaledMath.ONE, Error.INVALID_AMOUNT); require(communityReserve != address(0), "Community reserve must be set"); crvCommunityReserveShare = crvCommunityReserveShare_; emit SetCrvCommunityReserveShare(crvCommunityReserveShare_); return true; } /** * @notice Set the share of CVX to send to the Community Reserve. * @param cvxCommunityReserveShare_ New fee charged on CVX rewards for governance. * @return True if successfully set. */ function setCvxCommunityReserveShare(uint256 cvxCommunityReserveShare_) external onlyGovernance returns (bool) { require(cvxCommunityReserveShare_ <= ScaledMath.ONE, Error.INVALID_AMOUNT); require(communityReserve != address(0), "Community reserve must be set"); cvxCommunityReserveShare = cvxCommunityReserveShare_; emit SetCvxCommunityReserveShare(cvxCommunityReserveShare_); return true; } /** * @notice Set imbalance tolerance for Curve Pool deposits. * @dev Stored as a percent, e.g. 1% would be set as 0.01 * @param _imbalanceToleranceIn New imbalance tolarance in. * @return True if successfully set. */ function setImbalanceToleranceIn(uint256 _imbalanceToleranceIn) external onlyGovernance returns (bool) { imbalanceToleranceIn = _imbalanceToleranceIn; emit SetImbalanceToleranceIn(_imbalanceToleranceIn); return true; } /** * @notice Set imbalance tolerance for Curve Pool withdrawals. * @dev Stored as a percent, e.g. 1% would be set as 0.01 * @param _imbalanceToleranceOut New imbalance tolarance out. * @return True if successfully set. */ function setImbalanceToleranceOut(uint256 _imbalanceToleranceOut) external onlyGovernance returns (bool) { imbalanceToleranceOut = _imbalanceToleranceOut; emit SetImbalanceToleranceOut(_imbalanceToleranceOut); return true; } /** * @notice Set strategist. * @dev Can only be set by current strategist. * @param _strategist Address of new strategist. * @return True if successfully set. */ function setStrategist(address _strategist) external returns (bool) { require(msg.sender == strategist, Error.UNAUTHORIZED_ACCESS); strategist = _strategist; emit SetStrategist(_strategist); return true; } /** * @notice Add a reward token to list of extra reward tokens. * @dev These are tokens that are not the main assets of the strategy. For instance, temporary incentives. * @param token Address of token to add to reward token list. * @return True if successfully added. */ function addRewardToken(address token) external onlyGovernance returns (bool) { require( token != address(_CVX) && token != address(_CRV) && token != address(_WETH), Error.INVALID_TOKEN_TO_ADD ); if (_rewardTokens.contains(token)) return false; _rewardTokens.add(token); _setDex(token, _SUSHISWAP); IERC20(token).safeApprove(address(_SUSHISWAP), 0); IERC20(token).safeApprove(address(_SUSHISWAP), type(uint256).max); emit AddRewardToken(token); return true; } /** * @notice Remove a reward token. * @param token Address of token to remove from reward token list. * @return True if successfully removed. */ function removeRewardToken(address token) external onlyGovernance returns (bool) { if (!_rewardTokens.contains(token)) return false; if (!_rewardTokens.remove(token)) return false; emit RemoveRewardToken(token); return true; } /** * @notice Set the DEX that should be used for swapping for a specific coin. * If Uniswap is active, it will switch to SushiSwap and vice versa. * @dev Only SushiSwap and Uniswap are supported. * @param token Address of token for which the DEX should be updated. */ function swapDex(address token) external onlyGovernance returns (bool) { UniswapRouter02 currentDex = tokenDex[token]; require(address(currentDex) != address(0), Error.NO_DEX_SET); UniswapRouter02 newDex = currentDex == _SUSHISWAP ? _UNISWAP : _SUSHISWAP; _setDex(token, newDex); IERC20(token).safeApprove(address(newDex), 0); IERC20(token).safeApprove(address(newDex), type(uint256).max); emit SwapDex(token, address(newDex)); return true; } /** * @notice Returns the name of the strategy. * @return The name of the strategy. */ function name() external view override returns (string memory) { return "BkdEthCvx"; } /** * @notice Amount of rewards that can be harvested in the underlying. * @dev Includes rewards for CRV & CVX. * @return Estimated amount of underlying available to harvest. */ function harvestable() external view override returns (uint256) { uint256 crvAmount_ = rewards.earned(address(this)); if (crvAmount_ == 0) return 0; return _underlyingAmountOut( _CRV, crvAmount_.scaledMul(ScaledMath.ONE - crvCommunityReserveShare) ) + _underlyingAmountOut( _CVX, getCvxMintAmount(crvAmount_).scaledMul(ScaledMath.ONE - cvxCommunityReserveShare) ); } /** * @dev Contract does not stash tokens. */ function hasPendingFunds() external pure override returns (bool) { return false; } /** * @notice Get the total underlying balance of the strategy. * @dev This includes idle underlying, idle LP and LP deposited on Convex. * @return Underlying balance of strategy. */ function balance() public view override returns (uint256) { return _underlyingBalance() + _lpToUnderlying(_stakedBalance() + _lpBalance()); } /** * @dev Set the dex to use for a token. * @param token Address of token to set the dex for. * @param dex Dex to use for swaps with that token. */ function _setDex(address token, UniswapRouter02 dex) internal { tokenDex[token] = dex; } /** * @notice Swaps all balance of a token for WETH. * @param token Address of the token to swap for WETH. */ function _swapAllForWeth(IERC20 token) internal { uint256 amount = token.balanceOf(address(this)); return _swapForWeth(token, amount); } /** * @notice Swaps a token for WETH. * @param token Address of the token to swap for WETH. * @param amount Amount of the token to swap for WETH. */ function _swapForWeth(IERC20 token, uint256 amount) internal { if (amount == 0) return; // Handling CVX Swaps if (token == _CVX) { _CVX_ETH_CURVE_POOL.exchange( _CURVE_CVX_INDEX, _CURVE_ETH_INDEX, amount, amount .scaledMul(_addressProvider.getOracleProvider().getPriceETH(address(_CVX))) .scaledMul(slippageTolerance) ); return; } // Handling other swaps address[] memory path = new address[](2); path[0] = address(token); path[1] = address(_WETH); tokenDex[address(token)].swapExactTokensForTokens( amount, amount .scaledMul(_addressProvider.getOracleProvider().getPriceETH(address(token))) .scaledMul(slippageTolerance), path, address(this), block.timestamp ); } /** * @notice Swaps all available WETH for underlying. */ function _swapWethForUnderlying() internal { uint256 wethBalance = _WETH.balanceOf(address(this)); if (wethBalance == 0) return; _WETH.withdraw(wethBalance); } /** * @notice Sends a share of the current balance of CRV and CVX to the Community Reserve. */ function _sendCommunityReserveShare() internal { address communityReserve_ = communityReserve; if (communityReserve_ == address(0)) return; uint256 cvxCommunityReserveShare_ = cvxCommunityReserveShare; if (cvxCommunityReserveShare_ > 0) { uint256 cvxBalance_ = _CVX.balanceOf(address(this)); if (cvxBalance_ > 0) { _CVX.safeTransfer( communityReserve_, cvxBalance_.scaledMul(cvxCommunityReserveShare_) ); } } uint256 crvCommunityReserveShare_ = crvCommunityReserveShare; if (crvCommunityReserveShare_ > 0) { uint256 crvBalance_ = _CRV.balanceOf(address(this)); if (crvBalance_ > 0) { _CRV.safeTransfer( communityReserve_, crvBalance_.scaledMul(crvCommunityReserveShare_) ); } } } /** * @dev Get the balance of the underlying. */ function _underlyingBalance() internal view returns (uint256) { return address(this).balance; } /** * @dev Get the balance of the lp. */ function _lpBalance() internal view returns (uint256) { return lp.balanceOf(address(this)); } /** * @dev Get the balance of the underlying staked in the Curve pool. */ function _stakedBalance() internal view returns (uint256) { return rewards.balanceOf(address(this)); } /** * @notice Gets the amount of underlying that would be received by selling the token. * @return Underlying amount that would be received. */ function _underlyingAmountOut(IERC20 token, uint256 amountIn) internal view returns (uint256) { if (amountIn == 0) return 0; if (token == _CVX) { return _CVX_ETH_CURVE_POOL.get_dy(_CURVE_CVX_INDEX, _CURVE_ETH_INDEX, amountIn); } address[] memory path = new address[](2); path[0] = address(token); path[1] = address(_WETH); return tokenDex[address(token)].getAmountsOut(amountIn, path)[1]; } /** * @notice Calculates the minimum LP to accept when depositing underlying into Curve Pool. * @param _underlyingAmount Amount of underlying that is being deposited into Curve Pool. * @return The minimum LP balance to accept. */ function _minLpAccepted(uint256 _underlyingAmount) internal view returns (uint256) { return _underlyingToLp(_underlyingAmount).scaledMul(ScaledMath.ONE - imbalanceToleranceIn); } /** * @notice Calculates the maximum LP to accept burning when withdrawing amount from Curve Pool. * @param _underlyingAmount Amount of underlying that is being widthdrawn from Curve Pool. * @return The maximum LP balance to accept burning. */ function _maxLpBurned(uint256 _underlyingAmount) internal view returns (uint256) { return _underlyingToLp(_underlyingAmount).scaledMul(ScaledMath.ONE + imbalanceToleranceOut); } /** * @notice Calculates the minimum underlying to accept when burning LP tokens to withdraw from Curve Pool. * @param _lpAmount Amount of LP tokens being burned to withdraw from Curve Pool. * @return The minimum underlying balance to accept. */ function _minUnderlyingAccepted(uint256 _lpAmount) internal view returns (uint256) { return _lpToUnderlying(_lpAmount).scaledMul(ScaledMath.ONE - imbalanceToleranceOut); } /** * @notice Converts an amount of underlying into their estimated LP value. * @dev Uses get_virtual_price which is less suceptible to manipulation. * But is also less accurate to how much could be withdrawn. * @param _underlyingAmount Amount of underlying to convert. * @return The estimated value in the LP. */ function _underlyingToLp(uint256 _underlyingAmount) internal view returns (uint256) { return _underlyingAmount.scaledDiv(curvePool.get_virtual_price()); } /** * @notice Converts an amount of LP into their estimated underlying value. * @dev Uses get_virtual_price which is less suceptible to manipulation. * But is also less accurate to how much could be withdrawn. * @param _lpAmount Amount of LP to convert. * @return The estimated value in the underlying. */ function _lpToUnderlying(uint256 _lpAmount) internal view returns (uint256) { return _lpAmount.scaledMul(curvePool.get_virtual_price()); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"vault_","type":"address"},{"internalType":"address","name":"strategist_","type":"address"},{"internalType":"address","name":"curvePool_","type":"address"},{"internalType":"uint256","name":"convexPid_","type":"uint256"},{"internalType":"uint256","name":"curveIndex_","type":"uint256"},{"internalType":"contract IAddressProvider","name":"addressProvider_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"AddRewardToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"RemoveRewardToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"reserve","type":"address"}],"name":"SetCommunityReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetCrvCommunityReserveShare","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetCvxCommunityReserveShare","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetImbalanceToleranceIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetImbalanceToleranceOut","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetSlippageTolerance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"strategist","type":"address"}],"name":"SetStrategist","type":"event"},{"anonymous":false,"inputs":[],"name":"Shutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"newDex","type":"address"}],"name":"SwapDex","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawAll","type":"event"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"addRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"communityReserve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"convexPid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvCommunityReserveShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curvePool","outputs":[{"internalType":"contract ICurveSwapEth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxCommunityReserveShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crvEarned","type":"uint256"}],"name":"getCvxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasPendingFunds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"imbalanceToleranceIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imbalanceToleranceOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lp","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"removeRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"contract IRewardStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roleManager","outputs":[{"internalType":"contract IRoleManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_communityReserve","type":"address"}],"name":"setCommunityReserve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crvCommunityReserveShare_","type":"uint256"}],"name":"setCrvCommunityReserveShare","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cvxCommunityReserveShare_","type":"uint256"}],"name":"setCvxCommunityReserveShare","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_imbalanceToleranceIn","type":"uint256"}],"name":"setImbalanceToleranceIn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_imbalanceToleranceOut","type":"uint256"}],"name":"setImbalanceToleranceOut","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_slippageTolerance","type":"uint256"}],"name":"setSlippageTolerance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slippageTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"swapDex","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenDex","outputs":[{"internalType":"contract UniswapRouter02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101806040523480156200001257600080fd5b50604051620045eb380380620045eb83398101604081905262000035916200077d565b62000054816001600160a01b0316620002fc60201b620025301760201c565b6001600160a01b03908116608052670d7621dc58210000600090815587821660c052600680546001600160a01b03191688841617905585821660e05261014085905261016084905290821660a052604051631526fe2760e01b815260048101859052819073f403c135812408bfbe8713b5a23a04b3d48aae3190631526fe279060240160c060405180830381600087803b158015620000f257600080fd5b505af115801562000107573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012d919062000810565b50506001600160a01b038481166101005281166101205266027ca57357c0006001556624f2beb1aa000060025573d533a949740bb3306d119cc777fa900ba034cd5260005260076020527fed4c9b3ad13d2bf45175455fec325ef1713cf4b0f709952687da6d7332a081ba80546001600160a01b03191673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f179055929450919250620001cb915050565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b60005260076020527ff3af3b9da6ac33569932110b27324f490cadff82974ce0ccd88561c89e289b4a80546001600160a01b03191673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f1790556200026873f403c135812408bfbe8713b5a23a04b3d48aae31600019846001600160a01b03166200038e60201b620025bf179092919060201c565b620002ab734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b73b576491f1e6e5e62f1d8f26062ee822b40b0e0d46000196200038e602090811b620025bf17901c565b620002ee73d533a949740bb3306d119cc777fa900ba034cd5273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6000196200038e602090811b620025bf17901c565b50505050505050506200097d565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a7219060240160206040518083038186803b1580156200034d57600080fd5b505afa15801562000362573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200038891906200089f565b92915050565b8015806200041c5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015620003df57600080fd5b505afa158015620003f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041a9190620008bf565b155b620004945760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084015b60405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620004ec918591620004f116565b505050565b60006200054d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620005cf60201b6200271b179092919060201c565b805190915015620004ec57808060200190518101906200056e9190620008d9565b620004ec5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200048b565b6060620005e08484600085620005ea565b90505b9392505050565b6060824710156200064d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200048b565b6001600160a01b0385163b620006a65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200048b565b600080866001600160a01b03168587604051620006c491906200092a565b60006040518083038185875af1925050503d806000811462000703576040519150601f19603f3d011682016040523d82523d6000602084013e62000708565b606091505b5090925090506200071b82828662000726565b979650505050505050565b6060831562000737575081620005e3565b825115620007485782518084602001fd5b8160405162461bcd60e51b81526004016200048b919062000948565b6001600160a01b03811681146200077a57600080fd5b50565b60008060008060008060c087890312156200079757600080fd5b8651620007a48162000764565b6020880151909650620007b78162000764565b6040880151909550620007ca8162000764565b80945050606087015192506080870151915060a0870151620007ec8162000764565b809150509295509295509295565b805180151581146200080b57600080fd5b919050565b60008060008060008060c087890312156200082a57600080fd5b8651620008378162000764565b60208801519096506200084a8162000764565b60408801519095506200085d8162000764565b6060880151909450620008708162000764565b6080880151909350620008838162000764565b91506200089360a08801620007fa565b90509295509295509295565b600060208284031215620008b257600080fd5b8151620005e38162000764565b600060208284031215620008d257600080fd5b5051919050565b600060208284031215620008ec57600080fd5b620005e382620007fa565b60005b8381101562000914578181015183820152602001620008fa565b8381111562000924576000848401525b50505050565b600082516200093e818460208701620008f7565b9190910192915050565b602081526000825180602084015262000969816040850160208701620008f7565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161016051613b1a62000ad1600039600081816104cf01528181610d8c01528181611a700152611e8a0152600081816105180152611f5301526000818161059801528181610cec015281816111de0152818161199c0152818161205d0152612b9601526000818161039c01526127b301526000818161034801528181610dd701528181611a4001528181611ec801528181612bf401526131300152600081816106b501528181610bbb01528181610c1c01528181610e4b0152818161117d0152818161185601528181611b1701528181611dd8015261249701526000818161334d015261353b01526000818161022d0152818161070b0152818161090201528181610fea01528181611317015281816115580152818161167f0152818161187f01528181611bcd01528181612176015261229d0152613b1a6000f3fe6080604052600436106102125760003560e01c80637bdcdaff11610118578063c7b9d530116100a0578063e9eb50881161006f578063e9eb508814610663578063ecf8db0a14610683578063fbfa77cf146106a3578063fc0e74d1146106d7578063ff0af85b146106ec57600080fd5b8063c7b9d53014610610578063d03153aa14610630578063d0e30db014610646578063dbbd47d41461064e57600080fd5b80639b61a924116100e75780639b61a924146105705780639ec5a89414610586578063b69ef8a8146105ba578063bf86d690146105cf578063c2bddf31146105f057600080fd5b80637bdcdaff146104bd578063853828b6146104f157806386993bef146105065780639851bf381461053a57600080fd5b80633778851e1161019b57806349cabcdf1161016a57806349cabcdf1461043357806356be5f711461045357806361240eea14610469578063621e8fe11461047d57806370aa17261461049d57600080fd5b80633778851e146103be5780633d509c97146103de5780634641257d146103fe578063469656a21461041357600080fd5b80631c03e6cc116101e25780631c03e6cc146102f65780631fe4a68614610316578063218751b2146103365780632e1a7d4d1461036a578063313c06a01461038a57600080fd5b8062435da51461021e57806306fdde031461026a578063117da1ee146102a25780631a55820d146102d257600080fd5b3661021957005b600080fd5b34801561022a57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027657600080fd5b506040805180820182526009815268084d6c88ae8d086ecf60bb1b60208201529051610261919061375d565b3480156102ae57600080fd5b506102c26102bd366004613790565b610707565b6040519015158152602001610261565b3480156102de57600080fd5b506102e860025481565b604051908152602001610261565b34801561030257600080fd5b506102c26103113660046137c1565b6108fe565b34801561032257600080fd5b5060065461024d906001600160a01b031681565b34801561034257600080fd5b5061024d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037657600080fd5b506102c2610385366004613790565b610b8b565b34801561039657600080fd5b5061024d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ca57600080fd5b506102e86103d9366004613790565b610ed7565b3480156103ea57600080fd5b506102c26103f93660046137c1565b610fe6565b34801561040a57600080fd5b506102e861114d565b34801561041f57600080fd5b506102c261042e3660046137c1565b611313565b34801561043f57600080fd5b506102c261044e366004613790565b611554565b34801561045f57600080fd5b506102e860015481565b34801561047557600080fd5b5060006102c2565b34801561048957600080fd5b5060035461024d906001600160a01b031681565b3480156104a957600080fd5b506102c26104b8366004613790565b61167b565b3480156104c957600080fd5b506102e87f000000000000000000000000000000000000000000000000000000000000000081565b3480156104fd57600080fd5b506102e8611849565b34801561051257600080fd5b506102e87f000000000000000000000000000000000000000000000000000000000000000081565b34801561054657600080fd5b5061024d6105553660046137c1565b6007602052600090815260409020546001600160a01b031681565b34801561057c57600080fd5b506102e860045481565b34801561059257600080fd5b5061024d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105c657600080fd5b506102e8611b9b565b3480156105db57600080fd5b506006546102c290600160a01b900460ff1681565b3480156105fc57600080fd5b506102c261060b3660046137c1565b611bc9565b34801561061c57600080fd5b506102c261062b3660046137c1565b611d09565b34801561063c57600080fd5b506102e860005481565b6102c2611da8565b34801561065a57600080fd5b506102e861203c565b34801561066f57600080fd5b506102c261067e366004613790565b612172565b34801561068f57600080fd5b506102c261069e366004613790565b612299565b3480156106af57600080fd5b5061024d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e357600080fd5b506102c2612467565b3480156106f857600080fd5b506102e860055481565b905090565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561077e57600080fd5b505afa158015610792573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b691906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906108015760405162461bcd60e51b81526004016107f8919061375d565b60405180910390fd5b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670de0b6b3a764000083111561085f5760405162461bcd60e51b81526004016107f8919061375d565b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670b1a2bc2ec50000083116108bc5760405162461bcd60e51b81526004016107f8919061375d565b5060008290556040518281527fe4a7fd2711237e77309a9a16ff636a748dbf956fd91f6e6da800d9302f441a79906020015b60405180910390a1506001919050565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561097557600080fd5b505afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad91906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906109ef5760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14801590610a3a57506001600160a01b03821673d533a949740bb3306d119cc777fa900ba034cd5214155b8015610a6357506001600160a01b03821673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214155b60405180604001604052806014815260200173125b9d985b1a59081d1bdad95b881d1bc818591960621b81525090610aae5760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b03821660009081526009602052604090205415610ad557506000919050565b610ae0600883612734565b50610aff8273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f612749565b610b286001600160a01b03831673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f60006125bf565b610b526001600160a01b03831673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6000196125bf565b6040516001600160a01b03831681527f851bbb4304bf0768ed98b97e429b5bd1dcc1f194b36cd1650f40293e951ae393906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bf95760405162461bcd60e51b81526004016107f8919061375d565b5081610c0757506000919050565b47828110610c9d576040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169084156108fc029085906000818181858888f19350505050610c615750600092915050565b6040518381527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d9060200160405180910390a150600192915050565b6000610ca98285613816565b90506000610cb682612777565b90506000610cc261279b565b610ccc9083613816565b604051636197390160e11b815260048101829052600060248201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c32e720290604401602060405180830381600087803b158015610d3857600080fd5b505af1158015610d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7091906137de565b610d805750600095945050505050565b610d88613713565b83817f000000000000000000000000000000000000000000000000000000000000000060028110610dbb57610dbb61382d565b602002015260405163e310327360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e310327390610e0e9084908790600401613843565b600060405180830381600087803b158015610e2857600080fd5b505af1158015610e3c573d6000803e3d6000fd5b50506040516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016925089156108fc02915089906000818181858888f19350505050158015610e96573d6000803e3d6000fd5b506040518781527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d9060200160405180910390a15060019695505050505050565b600080734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2757600080fd5b505afa158015610f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5f919061387b565b90506000610f7769152d02c7e14af680000083613894565b90506103e88110610f8c575060009392505050565b6000610f9a826103e8613816565b905060006103e8610fab83886138b6565b610fb59190613894565b90506000610fce856a52b7d2dcc80cd2e4000000613816565b905080821115610fdc578091505b5095945050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561105d57600080fd5b505afa158015611071573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109591906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906110d75760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b0382166000908152600960205260409020546110fd57506000919050565b611108600883612836565b61111457506000919050565b6040516001600160a01b03831681527f36bd04094fa067bb9471a8fbdb0a6e8a43424a2566ad3a740c88973fa40a3118906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111bb5760405162461bcd60e51b81526004016107f8919061375d565b50600047604051637050ccd960e01b8152306004820152600060248201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637050ccd990604401600060405180830381600087803b15801561122a57600080fd5b505af115801561123e573d6000803e3d6000fd5b5050505061124a61284b565b611267734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6129e7565b61128473d533a949740bb3306d119cc777fa900ba034cd526129e7565b60005b6112916008612a71565b8110156112bd576112ab6112a6600883612a7b565b6129e7565b806112b5816138d5565b915050611287565b506112c6612a87565b60006112d28247613816565b90507f80f97f878e16410266694f134ddf012f2be424f54f8b5cafa107eccc51d00d588160405161130591815260200190565b60405180910390a191505090565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561138a57600080fd5b505afa15801561139e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c291906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906114045760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b03808316600090815260076020908152604091829020548251808401909352601d83527f6e6f2064657820686173206265656e2073657420666f7220746f6b656e0000009183019190915290911690816114795760405162461bcd60e51b81526004016107f8919061375d565b5060006001600160a01b03821673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f146114ba5773d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6114d0565b737a250d5630b4cf539739df2c5dacb4c659f2488d5b90506114dc8482612749565b6114f16001600160a01b0385168260006125bf565b6115076001600160a01b038516826000196125bf565b604080516001600160a01b038087168252831660208201527fcac2ded52b5e76b519f6013bcd694b2426f57750994e28325ae931943a49ead2910160405180910390a15060019392505050565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156115cb57600080fd5b505afa1580156115df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160391906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906116455760405162461bcd60e51b81526004016107f8919061375d565b5060018290556040518281527f4ede3e4e9f7997fda6ff4a12d6c43d5c9e1e2055065cbc15f902f504f72dc8c0906020016108ee565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156116f257600080fd5b505afa158015611706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172a91906137de565b604051806040016040528060138152602001600080516020613ac58339815191528152509061176c5760405162461bcd60e51b81526004016107f8919061375d565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a76400008311156117bb5760405162461bcd60e51b81526004016107f8919061375d565b506003546001600160a01b03166118145760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d7573742062652073657400000060448201526064016107f8565b60058290556040518281527f1a8542dffa4956932e66916113e6a123e123956172fbc0e2e59df92b8a87d8e6906020016108ee565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061192a57507f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192a91906137de565b604051806040016040528060138152602001600080516020613ac58339815191528152509061196c5760405162461bcd60e51b81526004016107f8919061375d565b506000611977612b7e565b90508015611a2c57604051636197390160e11b815260048101829052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c32e720290604401602060405180830381600087803b1580156119e857600080fd5b505af11580156119fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2091906137de565b611a2c57600091505090565b6000611a3661279b565b90508015611afa577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a4d01d2827f0000000000000000000000000000000000000000000000000000000000000000611a9885612bcd565b6040516001600160e01b031960e086901b1681526004810193909352600f9190910b60248301526044820152606401600060405180830381600087803b158015611ae157600080fd5b505af1158015611af5573d6000803e3d6000fd5b505050505b4780611b0a576000935050505090565b6040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169082156108fc029083906000818181858888f19350505050158015611b60573d6000803e3d6000fd5b506040518181527f3d5a341dc6a12221fcf31279cef3771f8fad757b2d9261f97605ccc17c2574249060200160405180910390a19392505050565b6000611bbf611ba861279b565b611bb0612b7e565b611bba91906138f0565b612bed565b61070290476138f0565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b158015611c4057600080fd5b505afa158015611c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7891906137de565b604051806040016040528060138152602001600080516020613ac583398151915281525090611cba5760405162461bcd60e51b81526004016107f8919061375d565b50600380546001600160a01b0319166001600160a01b0384169081179091556040519081527f17d7ba6682f162782054b119192f8e5b98fe7090b4bec7a55fc7075d9cd859ee906020016108ee565b6006546040805180820190915260138152600080516020613ac583398151915260208201526000916001600160a01b03163314611d595760405162461bcd60e51b81526004016107f8919061375d565b50600680546001600160a01b0319166001600160a01b0384169081179091556040519081527f46d58e3fa07bf19b1d27240f0e286b27e9f7c1b0d88933333fe833b60eec5412906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611e165760405162461bcd60e51b81526004016107f8919061375d565b5060065460408051808201909152601581527429ba3930ba32b3bc9034b99039b43aba103237bbb760591b602082015290600160a01b900460ff1615611e6f5760405162461bcd60e51b81526004016107f8919061375d565b504780611e7e57600091505090565b611e86613713565b81817f000000000000000000000000000000000000000000000000000000000000000060028110611eb957611eb961382d565b60200201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016630b4c7e4d8383611ef882612c8a565b6040518463ffffffff1660e01b8152600401611f15929190613843565b6000604051808303818588803b158015611f2e57600080fd5b505af1158015611f42573d6000803e3d6000fd5b505060405163303acfe760e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001602482015273f403c135812408bfbe8713b5a23a04b3d48aae3193506360759fce92506044019050602060405180830381600087803b158015611fbb57600080fd5b505af1158015611fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff391906137de565b6120005760009250505090565b6040518281527f4d6ce1e535dbade1c23defba91e23b8f791ce5edc0cc320257a2b364e4e384269060200160405180910390a160019250505090565b6040516246613160e11b815230600482015260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690628cc2629060240160206040518083038186803b15801561209e57600080fd5b505afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d6919061387b565b9050806120e557600091505090565b61212a734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b612125600454670de0b6b3a76400006121169190613816565b61211f85610ed7565b90612ca5565b612cc4565b61216273d533a949740bb3306d119cc777fa900ba034cd52612125600554670de0b6b3a764000061215b9190613816565b8590612ca5565b61216c91906138f0565b91505090565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156121e957600080fd5b505afa1580156121fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222191906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906122635760405162461bcd60e51b81526004016107f8919061375d565b5060028290556040518281527fb2861fed34a4613f8f25f46553a23408a3364ee9ddc4ef6714f0a81d856e41a7906020016108ee565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561231057600080fd5b505afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234891906137de565b604051806040016040528060138152602001600080516020613ac58339815191528152509061238a5760405162461bcd60e51b81526004016107f8919061375d565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a76400008311156123d95760405162461bcd60e51b81526004016107f8919061375d565b506003546001600160a01b03166124325760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d7573742062652073657400000060448201526064016107f8565b60048290556040518281527f2c3c7d70a1dfbfaf74447753b8a73e1323aa10b32b9209742db563671e14b13c906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146124d55760405162461bcd60e51b81526004016107f8919061375d565b50600654600160a01b900460ff16156124ee5750600090565b6006805460ff60a01b1916600160a01b1790556040517f4426aa1fb73e391071491fcfe21a88b5c38a0a0333a1f6e77161470439704cf890600090a150600190565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b60206040518083038186803b15801561258157600080fd5b505afa158015612595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b99190613908565b92915050565b8015806126485750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561260e57600080fd5b505afa158015612622573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612646919061387b565b155b6126b35760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016107f8565b6040516001600160a01b03831660248201526044810182905261271690849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612ed7565b505050565b606061272a8484600085612fa9565b90505b9392505050565b600061272d836001600160a01b0384166130da565b6001600160a01b03918216600090815260076020526040902080546001600160a01b03191691909216179055565b60006125b9600254670de0b6b3a764000061279291906138f0565b61211f84613129565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a08231906024015b60206040518083038186803b1580156127fe57600080fd5b505afa158015612812573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610702919061387b565b600061272d836001600160a01b0384166131c6565b6003546001600160a01b03168061285f5750565b6004548015612921576040516370a0823160e01b8152306004820152600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a082319060240160206040518083038186803b1580156128b557600080fd5b505afa1580156128c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ed919061387b565b9050801561291f5761291f836129038385612ca5565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b91906132b9565b505b6005548015612716576040516370a0823160e01b815230600482015260009073d533a949740bb3306d119cc777fa900ba034cd52906370a082319060240160206040518083038186803b15801561297757600080fd5b505afa15801561298b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129af919061387b565b905080156129e1576129e1846129c58385612ca5565b73d533a949740bb3306d119cc777fa900ba034cd5291906132b9565b50505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015612a2957600080fd5b505afa158015612a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a61919061387b565b9050612a6d82826132e9565b5050565b60006125b9825490565b600061272d838361365b565b6040516370a0823160e01b815230600482015260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a082319060240160206040518083038186803b158015612ad457600080fd5b505afa158015612ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b0c919061387b565b905080612b165750565b604051632e1a7d4d60e01b81526004810182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015612b6357600080fd5b505af1158015612b77573d6000803e3d6000fd5b5050505050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a08231906024016127e6565b60006125b9600254670de0b6b3a7640000612be89190613816565b61211f845b60006125b97f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b158015612c4b57600080fd5b505afa158015612c5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c83919061387b565b8390612ca5565b60006125b9600154670de0b6b3a76400006127929190613816565b6000670de0b6b3a7640000612cba83856138b6565b61272d9190613894565b600081612cd3575060006125b9565b6001600160a01b038316734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b1415612d905760405163556d6e9f60e01b815260016004820152600060248201526044810183905273b576491f1e6e5e62f1d8f26062ee822b40b0e0d49063556d6e9f9060640160206040518083038186803b158015612d5157600080fd5b505afa158015612d65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d89919061387b565b90506125b9565b6040805160028082526060820183526000926020830190803683370190505090508381600081518110612dc557612dc561382d565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110612e0d57612e0d61382d565b6001600160a01b039283166020918202929092018101919091528582166000908152600790915260409081902054905163d06ca61f60e01b815291169063d06ca61f90612e60908690859060040161397f565b60006040518083038186803b158015612e7857600080fd5b505afa158015612e8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612eb49190810190613998565b600181518110612ec657612ec661382d565b602002602001015191505092915050565b6000612f2c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661271b9092919063ffffffff16565b8051909150156127165780806020019051810190612f4a91906137de565b6127165760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107f8565b60608247101561300a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107f8565b6001600160a01b0385163b6130615760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107f8565b600080866001600160a01b0316858760405161307d9190613a56565b60006040518083038185875af1925050503d80600081146130ba576040519150601f19603f3d011682016040523d82523d6000602084013e6130bf565b606091505b50915091506130cf828286613685565b979650505050505050565b6000818152600183016020526040812054613121575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556125b9565b5060006125b9565b60006125b97f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561318757600080fd5b505afa15801561319b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131bf919061387b565b83906136be565b600081815260018301602052604081205480156132af5760006131ea600183613816565b85549091506000906131fe90600190613816565b905081811461326357600086600001828154811061321e5761321e61382d565b90600052602060002001549050808760000184815481106132415761324161382d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061327457613274613a72565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506125b9565b60009150506125b9565b6040516001600160a01b03831660248201526044810182905261271690849063a9059cbb60e01b906064016126df565b806132f2575050565b6001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14156134755773b576491f1e6e5e62f1d8f26062ee822b40b0e0d46001600160a01b0316635b41b908600160008461340e60005461211f61337a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166136d3565b60405163e5ec9db960e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b60048201526001600160a01b03919091169063e5ec9db99060240160206040518083038186803b1580156133cf57600080fd5b505afa1580156133e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613407919061387b565b8990612ca5565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b15801561345957600080fd5b505af115801561346d573d6000803e3d6000fd5b505050505050565b60408051600280825260608201835260009260208301908036833701905050905082816000815181106134aa576134aa61382d565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106134f2576134f261382d565b6001600160a01b039283166020918202929092018101919091528482166000908152600790915260408120549054908216916338ed17399185916135e2919061211f90613560907f0000000000000000000000000000000000000000000000000000000000000000166136d3565b60405163e5ec9db960e01b81526001600160a01b038b81166004830152919091169063e5ec9db99060240160206040518083038186803b1580156135a357600080fd5b505afa1580156135b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135db919061387b565b8890612ca5565b8430426040518663ffffffff1660e01b8152600401613605959493929190613a88565b600060405180830381600087803b15801561361f57600080fd5b505af1158015613633573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526129e19190810190613998565b60008260000182815481106136725761367261382d565b9060005260206000200154905092915050565b6060831561369457508161272d565b8251156136a45782518084602001fd5b8160405162461bcd60e51b81526004016107f8919061375d565b600081612cba670de0b6b3a7640000856138b6565b6040516321f8a72160e01b81526d37b930b1b632a83937bb34b232b960911b60048201526000906001600160a01b038316906321f8a72190602401612569565b60405180604001604052806002906020820280368337509192915050565b60005b8381101561374c578181015183820152602001613734565b838111156129e15750506000910152565b602081526000825180602084015261377c816040850160208701613731565b601f01601f19169190910160400192915050565b6000602082840312156137a257600080fd5b5035919050565b6001600160a01b03811681146137be57600080fd5b50565b6000602082840312156137d357600080fd5b813561272d816137a9565b6000602082840312156137f057600080fd5b8151801515811461272d57600080fd5b634e487b7160e01b600052601160045260246000fd5b60008282101561382857613828613800565b500390565b634e487b7160e01b600052603260045260246000fd5b60608101818460005b600281101561386b57815183526020928301929091019060010161384c565b5050508260408301529392505050565b60006020828403121561388d57600080fd5b5051919050565b6000826138b157634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156138d0576138d0613800565b500290565b60006000198214156138e9576138e9613800565b5060010190565b6000821982111561390357613903613800565b500190565b60006020828403121561391a57600080fd5b815161272d816137a9565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501945080840160005b838110156139745781516001600160a01b03168752958201959082019060010161394f565b509495945050505050565b82815260406020820152600061272a604083018461393b565b600060208083850312156139ab57600080fd5b825167ffffffffffffffff808211156139c357600080fd5b818501915085601f8301126139d757600080fd5b8151818111156139e9576139e9613925565b8060051b604051601f19603f83011681018181108582111715613a0e57613a0e613925565b604052918252848201925083810185019188831115613a2c57600080fd5b938501935b82851015613a4a57845184529385019392850192613a31565b98975050505050505050565b60008251613a68818460208701613731565b9190910192915050565b634e487b7160e01b600052603160045260246000fd5b85815284602082015260a060408201526000613aa760a083018661393b565b6001600160a01b039490941660608301525060800152939250505056fe756e617574686f72697a65642061636365737300000000000000000000000000a2646970667358221220ec5f479a0eb5308519f8caa4a9b569b9dd6afb321e14c0a704a6d683e9aef64964736f6c6343000809003300000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d000000000000000000000000d24f0164aedbe5676536deb4867cd3d58b4f5405000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f6702200000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a
Deployed Bytecode
0x6080604052600436106102125760003560e01c80637bdcdaff11610118578063c7b9d530116100a0578063e9eb50881161006f578063e9eb508814610663578063ecf8db0a14610683578063fbfa77cf146106a3578063fc0e74d1146106d7578063ff0af85b146106ec57600080fd5b8063c7b9d53014610610578063d03153aa14610630578063d0e30db014610646578063dbbd47d41461064e57600080fd5b80639b61a924116100e75780639b61a924146105705780639ec5a89414610586578063b69ef8a8146105ba578063bf86d690146105cf578063c2bddf31146105f057600080fd5b80637bdcdaff146104bd578063853828b6146104f157806386993bef146105065780639851bf381461053a57600080fd5b80633778851e1161019b57806349cabcdf1161016a57806349cabcdf1461043357806356be5f711461045357806361240eea14610469578063621e8fe11461047d57806370aa17261461049d57600080fd5b80633778851e146103be5780633d509c97146103de5780634641257d146103fe578063469656a21461041357600080fd5b80631c03e6cc116101e25780631c03e6cc146102f65780631fe4a68614610316578063218751b2146103365780632e1a7d4d1461036a578063313c06a01461038a57600080fd5b8062435da51461021e57806306fdde031461026a578063117da1ee146102a25780631a55820d146102d257600080fd5b3661021957005b600080fd5b34801561022a57600080fd5b507f00000000000000000000000083174c049116271f64a661b8371658792f62e3635b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027657600080fd5b506040805180820182526009815268084d6c88ae8d086ecf60bb1b60208201529051610261919061375d565b3480156102ae57600080fd5b506102c26102bd366004613790565b610707565b6040519015158152602001610261565b3480156102de57600080fd5b506102e860025481565b604051908152602001610261565b34801561030257600080fd5b506102c26103113660046137c1565b6108fe565b34801561032257600080fd5b5060065461024d906001600160a01b031681565b34801561034257600080fd5b5061024d7f000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f6702281565b34801561037657600080fd5b506102c2610385366004613790565b610b8b565b34801561039657600080fd5b5061024d7f00000000000000000000000006325440d014e39736583c165c2963ba99faf14e81565b3480156103ca57600080fd5b506102e86103d9366004613790565b610ed7565b3480156103ea57600080fd5b506102c26103f93660046137c1565b610fe6565b34801561040a57600080fd5b506102e861114d565b34801561041f57600080fd5b506102c261042e3660046137c1565b611313565b34801561043f57600080fd5b506102c261044e366004613790565b611554565b34801561045f57600080fd5b506102e860015481565b34801561047557600080fd5b5060006102c2565b34801561048957600080fd5b5060035461024d906001600160a01b031681565b3480156104a957600080fd5b506102c26104b8366004613790565b61167b565b3480156104c957600080fd5b506102e87f000000000000000000000000000000000000000000000000000000000000000081565b3480156104fd57600080fd5b506102e8611849565b34801561051257600080fd5b506102e87f000000000000000000000000000000000000000000000000000000000000001981565b34801561054657600080fd5b5061024d6105553660046137c1565b6007602052600090815260409020546001600160a01b031681565b34801561057c57600080fd5b506102e860045481565b34801561059257600080fd5b5061024d7f0000000000000000000000000a760466e1b4621579a82a39cb56dda2f4e70f0381565b3480156105c657600080fd5b506102e8611b9b565b3480156105db57600080fd5b506006546102c290600160a01b900460ff1681565b3480156105fc57600080fd5b506102c261060b3660046137c1565b611bc9565b34801561061c57600080fd5b506102c261062b3660046137c1565b611d09565b34801561063c57600080fd5b506102e860005481565b6102c2611da8565b34801561065a57600080fd5b506102e861203c565b34801561066f57600080fd5b506102c261067e366004613790565b612172565b34801561068f57600080fd5b506102c261069e366004613790565b612299565b3480156106af57600080fd5b5061024d7f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d81565b3480156106e357600080fd5b506102c2612467565b3480156106f857600080fd5b506102e860055481565b905090565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561077e57600080fd5b505afa158015610792573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b691906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906108015760405162461bcd60e51b81526004016107f8919061375d565b60405180910390fd5b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670de0b6b3a764000083111561085f5760405162461bcd60e51b81526004016107f8919061375d565b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670b1a2bc2ec50000083116108bc5760405162461bcd60e51b81526004016107f8919061375d565b5060008290556040518281527fe4a7fd2711237e77309a9a16ff636a748dbf956fd91f6e6da800d9302f441a79906020015b60405180910390a1506001919050565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561097557600080fd5b505afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad91906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906109ef5760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14801590610a3a57506001600160a01b03821673d533a949740bb3306d119cc777fa900ba034cd5214155b8015610a6357506001600160a01b03821673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214155b60405180604001604052806014815260200173125b9d985b1a59081d1bdad95b881d1bc818591960621b81525090610aae5760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b03821660009081526009602052604090205415610ad557506000919050565b610ae0600883612734565b50610aff8273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f612749565b610b286001600160a01b03831673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f60006125bf565b610b526001600160a01b03831673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6000196125bf565b6040516001600160a01b03831681527f851bbb4304bf0768ed98b97e429b5bd1dcc1f194b36cd1650f40293e951ae393906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d1614610bf95760405162461bcd60e51b81526004016107f8919061375d565b5081610c0757506000919050565b47828110610c9d576040516001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d169084156108fc029085906000818181858888f19350505050610c615750600092915050565b6040518381527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d9060200160405180910390a150600192915050565b6000610ca98285613816565b90506000610cb682612777565b90506000610cc261279b565b610ccc9083613816565b604051636197390160e11b815260048101829052600060248201529091507f0000000000000000000000000a760466e1b4621579a82a39cb56dda2f4e70f036001600160a01b03169063c32e720290604401602060405180830381600087803b158015610d3857600080fd5b505af1158015610d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7091906137de565b610d805750600095945050505050565b610d88613713565b83817f000000000000000000000000000000000000000000000000000000000000000060028110610dbb57610dbb61382d565b602002015260405163e310327360e01b81526001600160a01b037f000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f67022169063e310327390610e0e9084908790600401613843565b600060405180830381600087803b158015610e2857600080fd5b505af1158015610e3c573d6000803e3d6000fd5b50506040516001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d16925089156108fc02915089906000818181858888f19350505050158015610e96573d6000803e3d6000fd5b506040518781527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d9060200160405180910390a15060019695505050505050565b600080734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2757600080fd5b505afa158015610f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5f919061387b565b90506000610f7769152d02c7e14af680000083613894565b90506103e88110610f8c575060009392505050565b6000610f9a826103e8613816565b905060006103e8610fab83886138b6565b610fb59190613894565b90506000610fce856a52b7d2dcc80cd2e4000000613816565b905080821115610fdc578091505b5095945050505050565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561105d57600080fd5b505afa158015611071573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109591906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906110d75760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b0382166000908152600960205260409020546110fd57506000919050565b611108600883612836565b61111457506000919050565b6040516001600160a01b03831681527f36bd04094fa067bb9471a8fbdb0a6e8a43424a2566ad3a740c88973fa40a3118906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d16146111bb5760405162461bcd60e51b81526004016107f8919061375d565b50600047604051637050ccd960e01b8152306004820152600060248201529091507f0000000000000000000000000a760466e1b4621579a82a39cb56dda2f4e70f036001600160a01b031690637050ccd990604401600060405180830381600087803b15801561122a57600080fd5b505af115801561123e573d6000803e3d6000fd5b5050505061124a61284b565b611267734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6129e7565b61128473d533a949740bb3306d119cc777fa900ba034cd526129e7565b60005b6112916008612a71565b8110156112bd576112ab6112a6600883612a7b565b6129e7565b806112b5816138d5565b915050611287565b506112c6612a87565b60006112d28247613816565b90507f80f97f878e16410266694f134ddf012f2be424f54f8b5cafa107eccc51d00d588160405161130591815260200190565b60405180910390a191505090565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561138a57600080fd5b505afa15801561139e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c291906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906114045760405162461bcd60e51b81526004016107f8919061375d565b506001600160a01b03808316600090815260076020908152604091829020548251808401909352601d83527f6e6f2064657820686173206265656e2073657420666f7220746f6b656e0000009183019190915290911690816114795760405162461bcd60e51b81526004016107f8919061375d565b5060006001600160a01b03821673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f146114ba5773d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6114d0565b737a250d5630b4cf539739df2c5dacb4c659f2488d5b90506114dc8482612749565b6114f16001600160a01b0385168260006125bf565b6115076001600160a01b038516826000196125bf565b604080516001600160a01b038087168252831660208201527fcac2ded52b5e76b519f6013bcd694b2426f57750994e28325ae931943a49ead2910160405180910390a15060019392505050565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156115cb57600080fd5b505afa1580156115df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160391906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906116455760405162461bcd60e51b81526004016107f8919061375d565b5060018290556040518281527f4ede3e4e9f7997fda6ff4a12d6c43d5c9e1e2055065cbc15f902f504f72dc8c0906020016108ee565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156116f257600080fd5b505afa158015611706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172a91906137de565b604051806040016040528060138152602001600080516020613ac58339815191528152509061176c5760405162461bcd60e51b81526004016107f8919061375d565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a76400008311156117bb5760405162461bcd60e51b81526004016107f8919061375d565b506003546001600160a01b03166118145760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d7573742062652073657400000060448201526064016107f8565b60058290556040518281527f1a8542dffa4956932e66916113e6a123e123956172fbc0e2e59df92b8a87d8e6906020016108ee565b6000336001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d16148061192a57507f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192a91906137de565b604051806040016040528060138152602001600080516020613ac58339815191528152509061196c5760405162461bcd60e51b81526004016107f8919061375d565b506000611977612b7e565b90508015611a2c57604051636197390160e11b815260048101829052600060248201527f0000000000000000000000000a760466e1b4621579a82a39cb56dda2f4e70f036001600160a01b03169063c32e720290604401602060405180830381600087803b1580156119e857600080fd5b505af11580156119fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2091906137de565b611a2c57600091505090565b6000611a3661279b565b90508015611afa577f000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f670226001600160a01b0316631a4d01d2827f0000000000000000000000000000000000000000000000000000000000000000611a9885612bcd565b6040516001600160e01b031960e086901b1681526004810193909352600f9190910b60248301526044820152606401600060405180830381600087803b158015611ae157600080fd5b505af1158015611af5573d6000803e3d6000fd5b505050505b4780611b0a576000935050505090565b6040516001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d169082156108fc029083906000818181858888f19350505050158015611b60573d6000803e3d6000fd5b506040518181527f3d5a341dc6a12221fcf31279cef3771f8fad757b2d9261f97605ccc17c2574249060200160405180910390a19392505050565b6000611bbf611ba861279b565b611bb0612b7e565b611bba91906138f0565b612bed565b61070290476138f0565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b158015611c4057600080fd5b505afa158015611c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7891906137de565b604051806040016040528060138152602001600080516020613ac583398151915281525090611cba5760405162461bcd60e51b81526004016107f8919061375d565b50600380546001600160a01b0319166001600160a01b0384169081179091556040519081527f17d7ba6682f162782054b119192f8e5b98fe7090b4bec7a55fc7075d9cd859ee906020016108ee565b6006546040805180820190915260138152600080516020613ac583398151915260208201526000916001600160a01b03163314611d595760405162461bcd60e51b81526004016107f8919061375d565b50600680546001600160a01b0319166001600160a01b0384169081179091556040519081527f46d58e3fa07bf19b1d27240f0e286b27e9f7c1b0d88933333fe833b60eec5412906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d1614611e165760405162461bcd60e51b81526004016107f8919061375d565b5060065460408051808201909152601581527429ba3930ba32b3bc9034b99039b43aba103237bbb760591b602082015290600160a01b900460ff1615611e6f5760405162461bcd60e51b81526004016107f8919061375d565b504780611e7e57600091505090565b611e86613713565b81817f000000000000000000000000000000000000000000000000000000000000000060028110611eb957611eb961382d565b60200201526001600160a01b037f000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f6702216630b4c7e4d8383611ef882612c8a565b6040518463ffffffff1660e01b8152600401611f15929190613843565b6000604051808303818588803b158015611f2e57600080fd5b505af1158015611f42573d6000803e3d6000fd5b505060405163303acfe760e11b81527f000000000000000000000000000000000000000000000000000000000000001960048201526001602482015273f403c135812408bfbe8713b5a23a04b3d48aae3193506360759fce92506044019050602060405180830381600087803b158015611fbb57600080fd5b505af1158015611fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff391906137de565b6120005760009250505090565b6040518281527f4d6ce1e535dbade1c23defba91e23b8f791ce5edc0cc320257a2b364e4e384269060200160405180910390a160019250505090565b6040516246613160e11b815230600482015260009081906001600160a01b037f0000000000000000000000000a760466e1b4621579a82a39cb56dda2f4e70f031690628cc2629060240160206040518083038186803b15801561209e57600080fd5b505afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d6919061387b565b9050806120e557600091505090565b61212a734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b612125600454670de0b6b3a76400006121169190613816565b61211f85610ed7565b90612ca5565b612cc4565b61216273d533a949740bb3306d119cc777fa900ba034cd52612125600554670de0b6b3a764000061215b9190613816565b8590612ca5565b61216c91906138f0565b91505090565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b1580156121e957600080fd5b505afa1580156121fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222191906137de565b604051806040016040528060138152602001600080516020613ac5833981519152815250906122635760405162461bcd60e51b81526004016107f8919061375d565b5060028290556040518281527fb2861fed34a4613f8f25f46553a23408a3364ee9ddc4ef6714f0a81d856e41a7906020016108ee565b60007f00000000000000000000000083174c049116271f64a661b8371658792f62e363604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d148549060440160206040518083038186803b15801561231057600080fd5b505afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234891906137de565b604051806040016040528060138152602001600080516020613ac58339815191528152509061238a5760405162461bcd60e51b81526004016107f8919061375d565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a76400008311156123d95760405162461bcd60e51b81526004016107f8919061375d565b506003546001600160a01b03166124325760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d7573742062652073657400000060448201526064016107f8565b60048290556040518281527f2c3c7d70a1dfbfaf74447753b8a73e1323aa10b32b9209742db563671e14b13c906020016108ee565b6040805180820190915260138152600080516020613ac58339815191526020820152600090336001600160a01b037f00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d16146124d55760405162461bcd60e51b81526004016107f8919061375d565b50600654600160a01b900460ff16156124ee5750600090565b6006805460ff60a01b1916600160a01b1790556040517f4426aa1fb73e391071491fcfe21a88b5c38a0a0333a1f6e77161470439704cf890600090a150600190565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b60206040518083038186803b15801561258157600080fd5b505afa158015612595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b99190613908565b92915050565b8015806126485750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561260e57600080fd5b505afa158015612622573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612646919061387b565b155b6126b35760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016107f8565b6040516001600160a01b03831660248201526044810182905261271690849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612ed7565b505050565b606061272a8484600085612fa9565b90505b9392505050565b600061272d836001600160a01b0384166130da565b6001600160a01b03918216600090815260076020526040902080546001600160a01b03191691909216179055565b60006125b9600254670de0b6b3a764000061279291906138f0565b61211f84613129565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000006325440d014e39736583c165c2963ba99faf14e6001600160a01b0316906370a08231906024015b60206040518083038186803b1580156127fe57600080fd5b505afa158015612812573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610702919061387b565b600061272d836001600160a01b0384166131c6565b6003546001600160a01b03168061285f5750565b6004548015612921576040516370a0823160e01b8152306004820152600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a082319060240160206040518083038186803b1580156128b557600080fd5b505afa1580156128c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ed919061387b565b9050801561291f5761291f836129038385612ca5565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b91906132b9565b505b6005548015612716576040516370a0823160e01b815230600482015260009073d533a949740bb3306d119cc777fa900ba034cd52906370a082319060240160206040518083038186803b15801561297757600080fd5b505afa15801561298b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129af919061387b565b905080156129e1576129e1846129c58385612ca5565b73d533a949740bb3306d119cc777fa900ba034cd5291906132b9565b50505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015612a2957600080fd5b505afa158015612a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a61919061387b565b9050612a6d82826132e9565b5050565b60006125b9825490565b600061272d838361365b565b6040516370a0823160e01b815230600482015260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a082319060240160206040518083038186803b158015612ad457600080fd5b505afa158015612ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b0c919061387b565b905080612b165750565b604051632e1a7d4d60e01b81526004810182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015612b6357600080fd5b505af1158015612b77573d6000803e3d6000fd5b5050505050565b6040516370a0823160e01b81523060048201526000907f0000000000000000000000000a760466e1b4621579a82a39cb56dda2f4e70f036001600160a01b0316906370a08231906024016127e6565b60006125b9600254670de0b6b3a7640000612be89190613816565b61211f845b60006125b97f000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f670226001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b158015612c4b57600080fd5b505afa158015612c5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c83919061387b565b8390612ca5565b60006125b9600154670de0b6b3a76400006127929190613816565b6000670de0b6b3a7640000612cba83856138b6565b61272d9190613894565b600081612cd3575060006125b9565b6001600160a01b038316734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b1415612d905760405163556d6e9f60e01b815260016004820152600060248201526044810183905273b576491f1e6e5e62f1d8f26062ee822b40b0e0d49063556d6e9f9060640160206040518083038186803b158015612d5157600080fd5b505afa158015612d65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d89919061387b565b90506125b9565b6040805160028082526060820183526000926020830190803683370190505090508381600081518110612dc557612dc561382d565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110612e0d57612e0d61382d565b6001600160a01b039283166020918202929092018101919091528582166000908152600790915260409081902054905163d06ca61f60e01b815291169063d06ca61f90612e60908690859060040161397f565b60006040518083038186803b158015612e7857600080fd5b505afa158015612e8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612eb49190810190613998565b600181518110612ec657612ec661382d565b602002602001015191505092915050565b6000612f2c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661271b9092919063ffffffff16565b8051909150156127165780806020019051810190612f4a91906137de565b6127165760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107f8565b60608247101561300a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107f8565b6001600160a01b0385163b6130615760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107f8565b600080866001600160a01b0316858760405161307d9190613a56565b60006040518083038185875af1925050503d80600081146130ba576040519150601f19603f3d011682016040523d82523d6000602084013e6130bf565b606091505b50915091506130cf828286613685565b979650505050505050565b6000818152600183016020526040812054613121575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556125b9565b5060006125b9565b60006125b97f000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f670226001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561318757600080fd5b505afa15801561319b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131bf919061387b565b83906136be565b600081815260018301602052604081205480156132af5760006131ea600183613816565b85549091506000906131fe90600190613816565b905081811461326357600086600001828154811061321e5761321e61382d565b90600052602060002001549050808760000184815481106132415761324161382d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061327457613274613a72565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506125b9565b60009150506125b9565b6040516001600160a01b03831660248201526044810182905261271690849063a9059cbb60e01b906064016126df565b806132f2575050565b6001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14156134755773b576491f1e6e5e62f1d8f26062ee822b40b0e0d46001600160a01b0316635b41b908600160008461340e60005461211f61337a7f000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a6001600160a01b03166136d3565b60405163e5ec9db960e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b60048201526001600160a01b03919091169063e5ec9db99060240160206040518083038186803b1580156133cf57600080fd5b505afa1580156133e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613407919061387b565b8990612ca5565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b15801561345957600080fd5b505af115801561346d573d6000803e3d6000fd5b505050505050565b60408051600280825260608201835260009260208301908036833701905050905082816000815181106134aa576134aa61382d565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106134f2576134f261382d565b6001600160a01b039283166020918202929092018101919091528482166000908152600790915260408120549054908216916338ed17399185916135e2919061211f90613560907f000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a166136d3565b60405163e5ec9db960e01b81526001600160a01b038b81166004830152919091169063e5ec9db99060240160206040518083038186803b1580156135a357600080fd5b505afa1580156135b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135db919061387b565b8890612ca5565b8430426040518663ffffffff1660e01b8152600401613605959493929190613a88565b600060405180830381600087803b15801561361f57600080fd5b505af1158015613633573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526129e19190810190613998565b60008260000182815481106136725761367261382d565b9060005260206000200154905092915050565b6060831561369457508161272d565b8251156136a45782518084602001fd5b8160405162461bcd60e51b81526004016107f8919061375d565b600081612cba670de0b6b3a7640000856138b6565b6040516321f8a72160e01b81526d37b930b1b632a83937bb34b232b960911b60048201526000906001600160a01b038316906321f8a72190602401612569565b60405180604001604052806002906020820280368337509192915050565b60005b8381101561374c578181015183820152602001613734565b838111156129e15750506000910152565b602081526000825180602084015261377c816040850160208701613731565b601f01601f19169190910160400192915050565b6000602082840312156137a257600080fd5b5035919050565b6001600160a01b03811681146137be57600080fd5b50565b6000602082840312156137d357600080fd5b813561272d816137a9565b6000602082840312156137f057600080fd5b8151801515811461272d57600080fd5b634e487b7160e01b600052601160045260246000fd5b60008282101561382857613828613800565b500390565b634e487b7160e01b600052603260045260246000fd5b60608101818460005b600281101561386b57815183526020928301929091019060010161384c565b5050508260408301529392505050565b60006020828403121561388d57600080fd5b5051919050565b6000826138b157634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156138d0576138d0613800565b500290565b60006000198214156138e9576138e9613800565b5060010190565b6000821982111561390357613903613800565b500190565b60006020828403121561391a57600080fd5b815161272d816137a9565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501945080840160005b838110156139745781516001600160a01b03168752958201959082019060010161394f565b509495945050505050565b82815260406020820152600061272a604083018461393b565b600060208083850312156139ab57600080fd5b825167ffffffffffffffff808211156139c357600080fd5b818501915085601f8301126139d757600080fd5b8151818111156139e9576139e9613925565b8060051b604051601f19603f83011681018181108582111715613a0e57613a0e613925565b604052918252848201925083810185019188831115613a2c57600080fd5b938501935b82851015613a4a57845184529385019392850192613a31565b98975050505050505050565b60008251613a68818460208701613731565b9190910192915050565b634e487b7160e01b600052603160045260246000fd5b85815284602082015260a060408201526000613aa760a083018661393b565b6001600160a01b039490941660608301525060800152939250505056fe756e617574686f72697a65642061636365737300000000000000000000000000a2646970667358221220ec5f479a0eb5308519f8caa4a9b569b9dd6afb321e14c0a704a6d683e9aef64964736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d000000000000000000000000d24f0164aedbe5676536deb4867cd3d58b4f5405000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f6702200000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a
-----Decoded View---------------
Arg [0] : vault_ (address): 0x19750C9d273C2b47756ED96B54b930aD3A7F1a0d
Arg [1] : strategist_ (address): 0xd24F0164aEdbe5676536deb4867CD3d58b4f5405
Arg [2] : curvePool_ (address): 0xDC24316b9AE028F1497c275EB9192a3Ea0f67022
Arg [3] : convexPid_ (uint256): 25
Arg [4] : curveIndex_ (uint256): 0
Arg [5] : addressProvider_ (address): 0x139c15e21b0f6e43Fc397faCe5De5b7D5ae6874a
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000019750c9d273c2b47756ed96b54b930ad3a7f1a0d
Arg [1] : 000000000000000000000000d24f0164aedbe5676536deb4867cd3d58b4f5405
Arg [2] : 000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f67022
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000019
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a
Deployed Bytecode Sourcemap
67623:24431:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59708:108;;;;;;;;;;-1:-1:-1;60259:13:0;59708:108;;;-1:-1:-1;;;;;199:32:1;;;181:51;;169:2;154:18;59708:108:0;;;;;;;;83855:100;;;;;;;;;;-1:-1:-1;83929:18:0;;;;;;;;;;;-1:-1:-1;;;83929:18:0;;;;83855:100;;;;83929:18;83855:100;:::i;60978:435::-;;;;;;;;;;-1:-1:-1;60978:435:0;;;;;:::i;:::-;;:::i;:::-;;;1244:14:1;;1237:22;1219:41;;1207:2;1192:18;60978:435:0;1079:187:1;69497:36:0;;;;;;;;;;;;;;;;;;;1417:25:1;;;1405:2;1390:18;69497:36:0;1271:177:1;81877:571:0;;;;;;;;;;-1:-1:-1;81877:571:0;;;;;:::i;:::-;;:::i;69881:34::-;;;;;;;;;;-1:-1:-1;69881:34:0;;;;-1:-1:-1;;;;;69881:34:0;;;69012:40;;;;;;;;;;;;;;;74283:1097;;;;;;;;;;-1:-1:-1;74283:1097:0;;;;;:::i;:::-;;:::i;69073:26::-;;;;;;;;;;;;;;;49344:843;;;;;;;;;;-1:-1:-1;49344:843:0;;;;;:::i;:::-;;:::i;82631:267::-;;;;;;;;;;-1:-1:-1;82631:267:0;;;;;:::i;:::-;;:::i;76913:817::-;;;;;;;;;;;;;:::i;83218:519::-;;;;;;;;;;-1:-1:-1;83218:519:0;;;;;:::i;:::-;;:::i;80273:282::-;;;;;;;;;;-1:-1:-1;80273:282:0;;;;;:::i;:::-;;:::i;69386:35::-;;;;;;;;;;;;;;;;84759:96;;;;;;;;;;-1:-1:-1;84818:4:0;84759:96;;69610:31;;;;;;;;;;-1:-1:-1;69610:31:0;;;;-1:-1:-1;;;;;69610:31:0;;;78837:474;;;;;;;;;;-1:-1:-1;78837:474:0;;;;;:::i;:::-;;:::i;69308:35::-;;;;;;;;;;;;;;;75640:1051;;;;;;;;;;;;;:::i;69223:34::-;;;;;;;;;;;;;;;70037:51;;;;;;;;;;-1:-1:-1;70037:51:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;70037:51:0;;;69705:39;;;;;;;;;;;;;;;;69129;;;;;;;;;;;;;;;85075:155;;;;;;;;;;;;;:::i;69957:22::-;;;;;;;;;;-1:-1:-1;69957:22:0;;;;-1:-1:-1;;;69957:22:0;;;;;;78384:226;;;;;;;;;;-1:-1:-1;78384:226:0;;;;;:::i;:::-;;:::i;81315:246::-;;;;;;;;;;-1:-1:-1;81315:246:0;;;;;:::i;:::-;;:::i;60454:32::-;;;;;;;;;;;;;;;;73279:692;;;:::i;84170:518::-;;;;;;;;;;;;;:::i;80821:288::-;;;;;;;;;;-1:-1:-1;80821:288:0;;;;;:::i;:::-;;:::i;79538:474::-;;;;;;;;;;-1:-1:-1;79538:474:0;;;;;:::i;:::-;;:::i;68952:38::-;;;;;;;;;;;;;;;77879:186;;;;;;;;;;;;;:::i;69793:39::-;;;;;;;;;;;;;;;;59794:14;59787:21;;59708:108;:::o;60978:435::-;61096:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;61164:32:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;47934:4:::1;61126:36:::0;::::1;;61118:79;;;;-1:-1:-1::0;;;61118:79:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;61245:32:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;61237:6:::1;61216:27:::0;::::1;61208:70;;;;-1:-1:-1::0;;;61208:70:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;61289:17:0::1;:38:::0;;;61343:40:::1;::::0;1417:25:1;;;61343:40:0::1;::::0;1405:2:1;1390:18;61343:40:0::1;;;;;;;;-1:-1:-1::0;61401:4:0::1;60978:435:::0;;;:::o;81877:571::-;81949:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;81988:22:0;::::1;68144:42;81988:22;::::0;::::1;::::0;:48:::1;;-1:-1:-1::0;;;;;;82014:22:0;::::1;68334:42;82014:22;;81988:48;:75;;;;-1:-1:-1::0;;;;;;82040:23:0;::::1;68238:42;82040:23;;81988:75;82078:26;;;;;;;;;;;;;-1:-1:-1::0;;;82078:26:0::1;;::::0;81966:149:::1;;;;;-1:-1:-1::0;;;81966:149:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;24083:23:0;;24029:4;19485:19;;;:12;:19;;;;;;:24;82126:47:::1;;-1:-1:-1::0;82168:5:0::1;60978:435:::0;;;:::o;82126:47::-:1;82184:24;:13;82202:5:::0;82184:17:::1;:24::i;:::-;;82219:26;82227:5;68462:42;82219:7;:26::i;:::-;82256:49;-1:-1:-1::0;;;;;82256:25:0;::::1;68462:42;82303:1;82256:25;:49::i;:::-;82316:65;-1:-1:-1::0;;;;;82316:25:0;::::1;68462:42;-1:-1:-1::0;;82316:25:0::1;:65::i;:::-;82397:21;::::0;-1:-1:-1;;;;;199:32:1;;181:51;;82397:21:0::1;::::0;169:2:1;154:18;82397:21:0::1;14:224:1::0;74283:1097:0;71685:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;71685:25:0;;;;74354:4;;71664:10;-1:-1:-1;;;;;71678:5:0;71664:19;;71656:55;;;;-1:-1:-1;;;71656:55:0;;;;;;;;:::i;:::-;-1:-1:-1;74375:11:0;74371:29:::1;;-1:-1:-1::0;74395:5:0::1;60978:435:::0;;;:::o;74371:29::-:1;88549:21:::0;74529:27;;::::1;74525:159;;74578:18;::::0;-1:-1:-1;;;;;74578:5:0::1;:10;::::0;:18;::::1;;;::::0;74589:6;;74578:18:::1;::::0;;;74589:6;74578:10;:18;::::1;;;;;;74573:37;;-1:-1:-1::0;74605:5:0::1;::::0;60978:435;-1:-1:-1;;60978:435:0:o;74573:37::-:1;74630:16;::::0;1417:25:1;;;74630:16:0::1;::::0;1405:2:1;1390:18;74630:16:0::1;;;;;;;-1:-1:-1::0;74668:4:0::1;::::0;60978:435;-1:-1:-1;;60978:435:0:o;74525:159::-:1;74747:32;74782:26;74791:17:::0;74782:6;:26:::1;:::i;:::-;74747:61;;74819:19;74841:38;74854:24;74841:12;:38::i;:::-;74819:60;;74890:24;74931:12;:10;:12::i;:::-;74917:26;::::0;:11;:26:::1;:::i;:::-;74959:50;::::0;-1:-1:-1;;;74959:50:0;;::::1;::::0;::::1;4178:25:1::0;;;75003:5:0::1;4219:18:1::0;;;4212:50;74890:53:0;;-1:-1:-1;74959:7:0::1;-1:-1:-1::0;;;;;74959:25:0::1;::::0;::::1;::::0;4151:18:1;;74959:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74954:69;;-1:-1:-1::0;75018:5:0::1;::::0;60978:435;-1:-1:-1;;;;;60978:435:0:o;74954:69::-:1;75085:25;;:::i;:::-;75192:24;75170:7;75178:10;75170:19;;;;;;;:::i;:::-;;;;:46:::0;75227:58:::1;::::0;-1:-1:-1;;;75227:58:0;;-1:-1:-1;;;;;75227:9:0::1;:36;::::0;::::1;::::0;:58:::1;::::0;75264:7;;75273:11;;75227:58:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;75296:22:0::1;::::0;-1:-1:-1;;;;;75296:5:0::1;:14;::::0;-1:-1:-1;75296:22:0;::::1;;;::::0;-1:-1:-1;75311:6:0;;75296:22:::1;::::0;;;75311:6;75296:14;:22;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;75334:16:0::1;::::0;1417:25:1;;;75334:16:0::1;::::0;1405:2:1;1390:18;75334:16:0::1;;;;;;;-1:-1:-1::0;75368:4:0::1;::::0;74283:1097;-1:-1:-1;;;;;;74283:1097:0:o;49344:843::-;49410:7;49464:22;49278:42;-1:-1:-1;;;;;49489:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49464:49;-1:-1:-1;49555:20:0;49578:28;49014:13;49464:49;49578:28;:::i;:::-;49555:51;;49107:4;49668:12;:28;49664:42;;-1:-1:-1;49705:1:0;;49344:843;-1:-1:-1;;;49344:843:0:o;49664:42::-;49751:17;49771:27;49786:12;49107:4;49771:27;:::i;:::-;49751:47;-1:-1:-1;49901:17:0;49107:4;49922:21;49751:47;49922:9;:21;:::i;:::-;49921:38;;;;:::i;:::-;49901:58;-1:-1:-1;50033:21:0;50057:28;50071:14;49173:16;50057:28;:::i;:::-;50033:52;;50112:13;50100:9;:25;50096:56;;;50139:13;50127:25;;50096:56;-1:-1:-1;50170:9:0;49344:843;-1:-1:-1;;;;;49344:843:0:o;82631:267::-;82706:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;24083:23:0;;24029:4;19485:19;;;:12;:19;;;;;;82723:48:::1;;-1:-1:-1::0;82766:5:0::1;60978:435:::0;;;:::o;82723:48::-:1;82787:27;:13;82808:5:::0;82787:20:::1;:27::i;:::-;82782:46;;-1:-1:-1::0;82823:5:0::1;60978:435:::0;;;:::o;82782:46::-:1;82844:24;::::0;-1:-1:-1;;;;;199:32:1;;181:51;;82844:24:0::1;::::0;169:2:1;154:18;82844:24:0::1;14:224:1::0;76913:817:0;71685:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;71685:25:0;;;;76969:7;;71664:10;-1:-1:-1;;;;;71678:5:0;71664:19;;71656:55;;;;-1:-1:-1;;;71656:55:0;;;;;;;;:::i;:::-;-1:-1:-1;76989:25:0::1;88549:21:::0;77083:39:::1;::::0;-1:-1:-1;;;77083:39:0;;77109:4:::1;77083:39;::::0;::::1;5727:51:1::0;77116:5:0::1;5794:18:1::0;;;5787:50;76989:48:0;;-1:-1:-1;77083:7:0::1;-1:-1:-1::0;;;;;77083:17:0::1;::::0;::::1;::::0;5700:18:1;;77083:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;77182:28;:26;:28::i;:::-;77253:21;68144:42;77253:15;:21::i;:::-;77317;68334:42;77317:15;:21::i;:::-;77396:9;77391:124;77415:22;:13;:20;:22::i;:::-;77411:1;:26;77391:124;;;77459:44;77482:19;:13;77499:1:::0;77482:16:::1;:19::i;:::-;77459:15;:44::i;:::-;77439:3:::0;::::1;::::0;::::1;:::i;:::-;;;;77391:124;;;;77564:24;:22;:24::i;:::-;77601:17;77621:40;77644:17:::0;88549:21;77621:40:::1;:::i;:::-;77601:60;;77677:18;77685:9;77677:18;;;;1417:25:1::0;;1405:2;1390:18;;1271:177;77677:18:0::1;;;;;;;;77713:9:::0;-1:-1:-1;;76913:817:0;:::o;83218:519::-;83283:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;83329:15:0;;::::1;83300:26;83329:15:::0;;;:8:::1;:15;::::0;;;;;;;;;83398:16;;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;83329:15;;::::1;::::0;83363:33;83355:60:::1;;;;-1:-1:-1::0;;;83355:60:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;83426:22:0::1;-1:-1:-1::0;;;;;83451:24:0;::::1;68462:42;83451:24;:48;;68462:42;83451:48;;;68611:42;83451:48;83426:73;;83510:22;83518:5;83525:6;83510:7;:22::i;:::-;83543:45;-1:-1:-1::0;;;;;83543:25:0;::::1;83577:6:::0;83586:1:::1;83543:25;:45::i;:::-;83599:61;-1:-1:-1::0;;;;;83599:25:0;::::1;83633:6:::0;-1:-1:-1;;83599:25:0::1;:61::i;:::-;83676:31;::::0;;-1:-1:-1;;;;;6218:15:1;;;6200:34;;6270:15;;6265:2;6250:18;;6243:43;83676:31:0::1;::::0;6135:18:1;83676:31:0::1;;;;;;;-1:-1:-1::0;83725:4:0::1;::::0;83218:519;-1:-1:-1;;;83218:519:0:o;80273:282::-;80397:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;80419:20:0::1;:44:::0;;;80479:46:::1;::::0;1417:25:1;;;80479:46:0::1;::::0;1405:2:1;1390:18;80479:46:0::1;1271:177:1::0;78837:474:0;78969:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;79044:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;79044:20:0::1;::::0;::::1;::::0;47934:4:::1;78999:43:::0;::::1;;78991:74;;;;-1:-1:-1::0;;;78991:74:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;79084:16:0::1;::::0;-1:-1:-1;;;;;79084:16:0::1;79076:72;;;::::0;-1:-1:-1;;;79076:72:0;;6499:2:1;79076:72:0::1;::::0;::::1;6481:21:1::0;6538:2;6518:18;;;6511:30;6577:31;6557:18;;;6550:59;6626:18;;79076:72:0::1;6297:353:1::0;79076:72:0::1;79159:24;:52:::0;;;79227:54:::1;::::0;1417:25:1;;;79227:54:0::1;::::0;1405:2:1;1390:18;79227:54:0::1;1271:177:1::0;75640:1051:0;75690:7;75732:10;-1:-1:-1;;;;;75746:5:0;75732:19;;;:75;;-1:-1:-1;60259:13:0;75755:52;;-1:-1:-1;;;75755:52:0;;-1:-1:-1;;;75755:52:0;;;3361:25:1;75796:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;75755:22:0;;;;;;;3334:18:1;;75755:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75822:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;75822:25:0;;;75710:148;;;;;-1:-1:-1;;;75710:148:0;;;;;;;;:::i;:::-;;75924:21;75948:16;:14;:16::i;:::-;75924:40;-1:-1:-1;75979:17:0;;75975:112;;76018:47;;-1:-1:-1;;;76018:47:0;;;;;4178:25:1;;;76059:5:0;4219:18:1;;;4212:50;76018:7:0;-1:-1:-1;;;;;76018:25:0;;;;4151:18:1;;76018:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76013:62;;76074:1;76067:8;;;75640:1051;:::o;76013:62::-;76141:17;76161:12;:10;:12::i;:::-;76141:32;-1:-1:-1;76188:13:0;;76184:222;;76218:9;-1:-1:-1;;;;;76218:35:0;;76272:9;76315:10;76346:33;76369:9;76346:22;:33::i;:::-;76218:176;;-1:-1:-1;;;;;;76218:176:0;;;;;;;;;;6855:25:1;;;;6927:2;6916:22;;;;6896:18;;;6889:50;6955:18;;;6948:34;6828:18;;76218:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76184:222;88549:21;;76522:36;;76557:1;76550:8;;;;;75640:1051;:::o;76522:36::-;76569:33;;-1:-1:-1;;;;;76569:5:0;:14;;:33;;;;;76584:17;;76569:33;;;;76584:17;76569:14;:33;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76618:30:0;;1417:25:1;;;76618:30:0;;1405:2:1;1390:18;76618:30:0;;;;;;;76666:17;75640:1051;-1:-1:-1;;;75640:1051:0:o;85075:155::-;85124:7;85174:48;85209:12;:10;:12::i;:::-;85190:16;:14;:16::i;:::-;:31;;;;:::i;:::-;85174:15;:48::i;:::-;85151:71;;88549:21;85151:71;:::i;78384:226::-;78473:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;78490:16:0::1;:36:::0;;-1:-1:-1;;;;;;78490:36:0::1;-1:-1:-1::0;;;;;78490:36:0;::::1;::::0;;::::1;::::0;;;78542:38:::1;::::0;181:51:1;;;78542:38:0::1;::::0;169:2:1;154:18;78542:38:0::1;14:224:1::0;81315:246:0;81416:10;;81428:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;81428:25:0;;;;-1:-1:-1;;;;;;;81416:10:0;81402;:24;81394:60;;;;-1:-1:-1;;;81394:60:0;;;;;;;;:::i;:::-;-1:-1:-1;81465:10:0;:24;;-1:-1:-1;;;;;;81465:24:0;-1:-1:-1;;;;;81465:24:0;;;;;;;;81505:26;;181:51:1;;;81505:26:0;;169:2:1;154:18;81505:26:0;14:224:1;73279:692:0;71685:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;71685:25:0;;;;73343:4;;71664:10;-1:-1:-1;;;;;71678:5:0;71664:19;;71656:55;;;;-1:-1:-1;;;71656:55:0;;;;;;;;:::i;:::-;-1:-1:-1;73369:10:0::1;::::0;73381:24:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;73381:24:0::1;::::0;::::1;::::0;;-1:-1:-1;;;73369:10:0;::::1;;;73368:11;73360:46;;;;-1:-1:-1::0;;;73360:46:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;88549:21:0;;73517:40:::1;;73552:5;73545:12;;;76913:817:::0;:::o;73517:40::-:1;73568:25;;:::i;:::-;73626:17;73604:7;73612:10;73604:19;;;;;;;:::i;:::-;;;;:39:::0;-1:-1:-1;;;;;73654:9:0::1;:23;;73685:17:::0;73718:7;73740:33:::1;73685:17:::0;73740:14:::1;:33::i;:::-;73654:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;73849:36:0::1;::::0;-1:-1:-1;;;73849:36:0;;73869:9:::1;73849:36;::::0;::::1;4178:25:1::0;73880:4:0::1;4219:18:1::0;;;4212:50;68029:42:0::1;::::0;-1:-1:-1;73849:19:0::1;::::0;-1:-1:-1;4151:18:1;;;-1:-1:-1;73849:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73844:55;;73894:5;73887:12;;;;76913:817:::0;:::o;73844:55::-:1;73915:26;::::0;1417:25:1;;;73915:26:0::1;::::0;1405:2:1;1390:18;73915:26:0::1;;;;;;;73959:4;73952:11;;;;73279:692:::0;:::o;84170:518::-;84266:29;;-1:-1:-1;;;84266:29:0;;84289:4;84266:29;;;181:51:1;84225:7:0;;;;-1:-1:-1;;;;;84266:7:0;:14;;;;154:18:1;;84266:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84245:50;-1:-1:-1;84310:15:0;84306:29;;84334:1;84327:8;;;84170:518;:::o;84306:29::-;84522:158;68144:42;84584:81;84640:24;;47934:4;84623:41;;;;:::i;:::-;84584:28;84601:10;84584:16;:28::i;:::-;:38;;:81::i;:::-;84522:20;:158::i;:::-;84366:140;68334:42;84428:63;84466:24;;47934:4;84449:41;;;;:::i;:::-;84428:10;;:20;:63::i;84366:140::-;:314;;;;:::i;:::-;84346:334;;;84170:518;:::o;80821:288::-;80947:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;80969:21:0::1;:46:::0;;;81031:48:::1;::::0;1417:25:1;;;81031:48:0::1;::::0;1405:2:1;1390:18;81031:48:0::1;1271:177:1::0;79538:474:0;79670:4;60259:13;58949:52;;-1:-1:-1;;;58949:52:0;;-1:-1:-1;;;58949:52:0;;;3361:25:1;58990:10:0;3402:18:1;;;3395:60;-1:-1:-1;;;;;58949:22:0;;;;;;;3334:18:1;;58949:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59003:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59003:25:0;;;58941:88;;;;;-1:-1:-1;;;58941:88:0;;;;;;;;:::i;:::-;-1:-1:-1;79745:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;79745:20:0::1;::::0;::::1;::::0;47934:4:::1;79700:43:::0;::::1;;79692:74;;;;-1:-1:-1::0;;;79692:74:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;79785:16:0::1;::::0;-1:-1:-1;;;;;79785:16:0::1;79777:72;;;::::0;-1:-1:-1;;;79777:72:0;;6499:2:1;79777:72:0::1;::::0;::::1;6481:21:1::0;6538:2;6518:18;;;6511:30;6577:31;6557:18;;;6550:59;6626:18;;79777:72:0::1;6297:353:1::0;79777:72:0::1;79860:24;:52:::0;;;79928:54:::1;::::0;1417:25:1;;;79928:54:0::1;::::0;1405:2:1;1390:18;79928:54:0::1;1271:177:1::0;77879:186:0;71685:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;71685:25:0;;;;77936:4;;71664:10;-1:-1:-1;;;;;71678:5:0;71664:19;;71656:55;;;;-1:-1:-1;;;71656:55:0;;;;;;;;:::i;:::-;-1:-1:-1;77957:10:0::1;::::0;-1:-1:-1;;;77957:10:0;::::1;;;77953:28;;;-1:-1:-1::0;77976:5:0::1;76913:817:::0;:::o;77953:28::-:1;77992:10;:17:::0;;-1:-1:-1;;;;77992:17:0::1;-1:-1:-1::0;;;77992:17:0::1;::::0;;78025:10:::1;::::0;::::1;::::0;77992:17;;78025:10:::1;-1:-1:-1::0;78053:4:0::1;77879:186:::0;:::o;46912:::-;47031:58;;-1:-1:-1;;;47031:58:0;;-1:-1:-1;;;47031:58:0;;;1417:25:1;46986:12:0;;-1:-1:-1;;;;;47031:19:0;;;;;1390:18:1;;47031:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47011:79;46912:186;-1:-1:-1;;46912:186:0:o;12939:616::-;13303:10;;;13302:62;;-1:-1:-1;13319:39:0;;-1:-1:-1;;;13319:39:0;;13343:4;13319:39;;;6200:34:1;-1:-1:-1;;;;;6270:15:1;;;6250:18;;;6243:43;13319:15:0;;;;;6135:18:1;;13319:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;13302:62;13280:166;;;;-1:-1:-1;;;13280:166:0;;7766:2:1;13280:166:0;;;7748:21:1;7805:2;7785:18;;;7778:30;7844:34;7824:18;;;7817:62;-1:-1:-1;;;7895:18:1;;;7888:52;7957:19;;13280:166:0;7564:418:1;13280:166:0;13484:62;;-1:-1:-1;;;;;8179:32:1;;13484:62:0;;;8161:51:1;8228:18;;;8221:34;;;13457:90:0;;13477:5;;-1:-1:-1;;;13507:22:0;8134:18:1;;13484:62:0;;;;-1:-1:-1;;13484:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;13484:62:0;-1:-1:-1;;;;;;13484:62:0;;;;;;;;;;13457:19;:90::i;:::-;12939:616;;;:::o;6977:229::-;7114:12;7146:52;7168:6;7176:4;7182:1;7185:12;7146:21;:52::i;:::-;7139:59;;6977:229;;;;;;:::o;23377:152::-;23447:4;23471:50;23476:3;-1:-1:-1;;;;;23496:23:0;;23471:4;:50::i;85416:102::-;-1:-1:-1;;;;;85489:15:0;;;;;;;:8;:15;;;;;:21;;-1:-1:-1;;;;;;85489:21:0;;;;;;;;85416:102::o;90352:191::-;90424:7;90451:84;90513:21;;47934:4;90496:38;;;;:::i;:::-;90451:34;90467:17;90451:15;:34::i;88644:107::-;88716:27;;-1:-1:-1;;;88716:27:0;;88737:4;88716:27;;;181:51:1;88689:7:0;;88716:2;-1:-1:-1;;;;;88716:12:0;;;;154:18:1;;88716:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;23705:158::-;23778:4;23802:53;23810:3;-1:-1:-1;;;;;23830:23:0;;23802:7;:53::i;87409:986::-;87495:16;;-1:-1:-1;;;;;87495:16:0;87526:31;87522:44;;87559:7;87409:986::o;87522:44::-;87612:24;;87651:29;;87647:330;;87719:29;;-1:-1:-1;;;87719:29:0;;87742:4;87719:29;;;181:51:1;87697:19:0;;68144:42;;87719:14;;154:18:1;;87719:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87697:51;-1:-1:-1;87767:15:0;;87763:203;;87803:147;87843:17;87883:48;:11;87905:25;87883:21;:48::i;:::-;68144:42;;87803:147;:17;:147::i;:::-;87682:295;87647:330;88023:24;;88062:29;;88058:330;;88130:29;;-1:-1:-1;;;88130:29:0;;88153:4;88130:29;;;181:51:1;88108:19:0;;68334:42;;88130:14;;154:18:1;;88130:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88108:51;-1:-1:-1;88178:15:0;;88174:203;;88214:147;88254:17;88294:48;:11;88316:25;88294:21;:48::i;:::-;68334:42;;88214:147;:17;:147::i;:::-;88093:295;87456:939;;;87409:986::o;85659:159::-;85735:30;;-1:-1:-1;;;85735:30:0;;85759:4;85735:30;;;181:51:1;85718:14:0;;-1:-1:-1;;;;;85735:15:0;;;;;154:18:1;;85735:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85718:47;;85783:27;85796:5;85803:6;85783:12;:27::i;:::-;85776:34;85659:159;:::o;24202:117::-;24265:7;24292:19;24300:3;19686:18;;19603:109;24673:158;24747:7;24798:22;24802:3;24814:5;24798:3;:22::i;87098:191::-;87174:30;;-1:-1:-1;;;87174:30:0;;87198:4;87174:30;;;181:51:1;87152:19:0;;68238:42;;87174:15;;154:18:1;;87174:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87152:52;-1:-1:-1;87219:16:0;87215:29;;87237:7;87098:191::o;87215:29::-;87254:27;;-1:-1:-1;;;87254:27:0;;;;;1417:25:1;;;68238:42:0;;87254:14;;1390:18:1;;87254:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87141:148;87098:191::o;88850:116::-;88926:32;;-1:-1:-1;;;88926:32:0;;88952:4;88926:32;;;181:51:1;88899:7:0;;88926;-1:-1:-1;;;;;88926:17:0;;;;154:18:1;;88926:32:0;14:224:1;90826:185:0;90900:7;90927:76;90981:21;;47934:4;90964:38;;;;:::i;:::-;90927:26;90943:9;91899:152;91966:7;91993:50;92013:9;-1:-1:-1;;;;;92013:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91993:9;;:19;:50::i;89879:192::-;89953:7;89980:83;90042:20;;47934:4;90025:37;;;;:::i;48034:122::-;48098:7;47825:4;48126:5;48130:1;48126;:5;:::i;:::-;48125:23;;;;:::i;89141:471::-;89226:7;89250:13;89246:27;;-1:-1:-1;89272:1:0;89265:8;;89246:27;-1:-1:-1;;;;;89288:13:0;;68144:42;89288:13;89284:125;;;89325:72;;-1:-1:-1;;;89325:72:0;;67921:1;89325:72;;;8468:25:1;67973:1:0;8509:18:1;;;8502:34;8552:18;;;8545:34;;;68766:42:0;;89325:26;;8441:18:1;;89325:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89318:79;;;;89284:125;89443:16;;;89457:1;89443:16;;;;;;;;89419:21;;89443:16;;;;;;;;;;-1:-1:-1;89443:16:0;89419:40;;89488:5;89470:4;89475:1;89470:7;;;;;;;;:::i;:::-;;;;;;:24;-1:-1:-1;;;;;89470:24:0;;;-1:-1:-1;;;;;89470:24:0;;;;;68238:42;89505:4;89510:1;89505:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;89505:24:0;;;:7;;;;;;;;;;:24;;;;89547;;;;;;;:8;:24;;;;;;;;;:54;;-1:-1:-1;;;89547:54:0;;:24;;;:38;;:54;;89586:8;;89596:4;;89547:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;89547:54:0;;;;;;;;;;;;:::i;:::-;89602:1;89547:57;;;;;;;;:::i;:::-;;;;;;;89540:64;;;89141:471;;;;:::o;14776:716::-;15200:23;15226:69;15254:4;15226:69;;;;;;;;;;;;;;;;;15234:5;-1:-1:-1;;;;;15226:27:0;;;:69;;;;;:::i;:::-;15310:17;;15200:95;;-1:-1:-1;15310:21:0;15306:179;;15407:10;15396:30;;;;;;;;;;;;:::i;:::-;15388:85;;;;-1:-1:-1;;;15388:85:0;;10837:2:1;15388:85:0;;;10819:21:1;10876:2;10856:18;;;10849:30;10915:34;10895:18;;;10888:62;-1:-1:-1;;;10966:18:1;;;10959:40;11016:19;;15388:85:0;10635:406:1;8097:510:0;8267:12;8325:5;8300:21;:30;;8292:81;;;;-1:-1:-1;;;8292:81:0;;11248:2:1;8292:81:0;;;11230:21:1;11287:2;11267:18;;;11260:30;11326:34;11306:18;;;11299:62;-1:-1:-1;;;11377:18:1;;;11370:36;11423:19;;8292:81:0;11046:402:1;8292:81:0;-1:-1:-1;;;;;4527:19:0;;;8384:60;;;;-1:-1:-1;;;8384:60:0;;11655:2:1;8384:60:0;;;11637:21:1;11694:2;11674:18;;;11667:30;11733:31;11713:18;;;11706:59;11782:18;;8384:60:0;11453:353:1;8384:60:0;8458:12;8472:23;8499:6;-1:-1:-1;;;;;8499:11:0;8518:5;8525:4;8499:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8457:73;;;;8548:51;8565:7;8574:10;8586:12;8548:16;:51::i;:::-;8541:58;8097:510;-1:-1:-1;;;;;;;8097:510:0:o;17292:414::-;17355:4;19485:19;;;:12;;;:19;;;;;;17372:327;;-1:-1:-1;17415:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;17598:18;;17576:19;;;:12;;;:19;;;;;;:40;;;;17631:11;;17372:327;-1:-1:-1;17682:5:0;17675:12;;91375:168;91450:7;91477:58;91505:9;-1:-1:-1;;;;;91505:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91477:17;;:27;:58::i;17882:1420::-;17948:4;18087:19;;;:12;;;:19;;;;;;18123:15;;18119:1176;;18498:21;18522:14;18535:1;18522:10;:14;:::i;:::-;18571:18;;18498:38;;-1:-1:-1;18551:17:0;;18571:22;;18592:1;;18571:22;:::i;:::-;18551:42;;18627:13;18614:9;:26;18610:405;;18661:17;18681:3;:11;;18693:9;18681:22;;;;;;;;:::i;:::-;;;;;;;;;18661:42;;18835:9;18806:3;:11;;18818:13;18806:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;18920:23;;;:12;;;:23;;;;;:36;;;18610:405;19096:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;19191:3;:12;;:19;19204:5;19191:19;;;;;;;;;;;19184:26;;;19234:4;19227:11;;;;;;;18119:1176;19278:5;19271:12;;;;;12203:211;12347:58;;-1:-1:-1;;;;;8179:32:1;;12347:58:0;;;8161:51:1;8228:18;;;8221:34;;;12320:86:0;;12340:5;;-1:-1:-1;;;12370:23:0;8134:18:1;;12347:58:0;7987:274:1;86004:1011:0;86080:11;86076:24;;86004:1011;;:::o;86076:24::-;-1:-1:-1;;;;;86147:13:0;;68144:42;86147:13;86143:378;;;68766:42;-1:-1:-1;;;;;86177:28:0;;67921:1;67973;86294:6;86319:154;86455:17;;86319:103;86358:36;:16;-1:-1:-1;;;;;86358:34:0;;:36::i;:::-;:63;;-1:-1:-1;;;86358:63:0;;68144:42;86358:63;;;181:51:1;-1:-1:-1;;;;;86358:48:0;;;;;;;154:18:1;;86358:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86319:6;;:38;:103::i;:154::-;86177:311;;-1:-1:-1;;;;;;86177:311:0;;;;;;;;;;12453:25:1;;;;12494:18;;;12487:34;;;;12537:18;;;12530:34;12580:18;;;12573:34;12425:19;;86177:311:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86004:1011;;:::o;86143:378::-;86590:16;;;86604:1;86590:16;;;;;;;;86566:21;;86590:16;;;;;;;;;;-1:-1:-1;86590:16:0;86566:40;;86635:5;86617:4;86622:1;86617:7;;;;;;;;:::i;:::-;;;;;;:24;-1:-1:-1;;;;;86617:24:0;;;-1:-1:-1;;;;;86617:24:0;;;;;68238:42;86652:4;86657:1;86652:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;86652:24:0;;;:7;;;;;;;;;;:24;;;;86687;;;;;;;:8;:24;;;;;;;86901:17;;86687:24;;;;:49;;86751:6;;86772:147;;86901:17;86772:100;;86807:36;;:16;:34;;:36::i;:::-;:64;;-1:-1:-1;;;86807:64:0;;-1:-1:-1;;;;;199:32:1;;;86807:64:0;;;181:51:1;86807:48:0;;;;;;;154:18:1;;86807:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86772:6;;:34;:100::i;:147::-;86934:4;86961;86981:15;86687:320;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;86687:320:0;;;;;;;;;;;;:::i;20066:120::-;20133:7;20160:3;:11;;20172:5;20160:18;;;;;;;;:::i;:::-;;;;;;;;;20153:25;;20066:120;;;;:::o;10783:712::-;10933:12;10962:7;10958:530;;;-1:-1:-1;10993:10:0;10986:17;;10958:530;11107:17;;:21;11103:374;;11305:10;11299:17;11366:15;11353:10;11349:2;11345:19;11338:44;11103:374;11448:12;11441:20;;-1:-1:-1;;;11441:20:0;;;;;;;;:::i;48245:122::-;48309:7;48358:1;48337:17;47825:4;48337:1;:17;:::i;46407:198::-;46535:61;;-1:-1:-1;;;46535:61:0;;-1:-1:-1;;;46535:61:0;;;1417:25:1;46484:15:0;;-1:-1:-1;;;;;46535:19:0;;;;;1390:18:1;;46535:61:0;1271:177:1;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;:::o;243:258:1:-;315:1;325:113;339:6;336:1;333:13;325:113;;;415:11;;;409:18;396:11;;;389:39;361:2;354:10;325:113;;;456:6;453:1;450:13;447:48;;;-1:-1:-1;;491:1:1;473:16;;466:27;243:258::o;506:383::-;655:2;644:9;637:21;618:4;687:6;681:13;730:6;725:2;714:9;710:18;703:34;746:66;805:6;800:2;789:9;785:18;780:2;772:6;768:15;746:66;:::i;:::-;873:2;852:15;-1:-1:-1;;848:29:1;833:45;;;;880:2;829:54;;506:383;-1:-1:-1;;506:383:1:o;894:180::-;953:6;1006:2;994:9;985:7;981:23;977:32;974:52;;;1022:1;1019;1012:12;974:52;-1:-1:-1;1045:23:1;;894:180;-1:-1:-1;894:180:1:o;1453:131::-;-1:-1:-1;;;;;1528:31:1;;1518:42;;1508:70;;1574:1;1571;1564:12;1508:70;1453:131;:::o;1589:247::-;1648:6;1701:2;1689:9;1680:7;1676:23;1672:32;1669:52;;;1717:1;1714;1707:12;1669:52;1756:9;1743:23;1775:31;1800:5;1775:31;:::i;3466:277::-;3533:6;3586:2;3574:9;3565:7;3561:23;3557:32;3554:52;;;3602:1;3599;3592:12;3554:52;3634:9;3628:16;3687:5;3680:13;3673:21;3666:5;3663:32;3653:60;;3709:1;3706;3699:12;3748:127;3809:10;3804:3;3800:20;3797:1;3790:31;3840:4;3837:1;3830:15;3864:4;3861:1;3854:15;3880:125;3920:4;3948:1;3945;3942:8;3939:34;;;3953:18;;:::i;:::-;-1:-1:-1;3990:9:1;;3880:125::o;4273:127::-;4334:10;4329:3;4325:20;4322:1;4315:31;4365:4;4362:1;4355:15;4389:4;4386:1;4379:15;4405:565;4613:2;4598:18;;4602:9;4693:6;4571:4;4727:194;4741:4;4738:1;4735:11;4727:194;;;4800:13;;4788:26;;4837:4;4861:12;;;;4896:15;;;;4761:1;4754:9;4727:194;;;4731:3;;;4957:6;4952:2;4941:9;4937:18;4930:34;4405:565;;;;;:::o;4975:184::-;5045:6;5098:2;5086:9;5077:7;5073:23;5069:32;5066:52;;;5114:1;5111;5104:12;5066:52;-1:-1:-1;5137:16:1;;4975:184;-1:-1:-1;4975:184:1:o;5164:217::-;5204:1;5230;5220:132;;5274:10;5269:3;5265:20;5262:1;5255:31;5309:4;5306:1;5299:15;5337:4;5334:1;5327:15;5220:132;-1:-1:-1;5366:9:1;;5164:217::o;5386:168::-;5426:7;5492:1;5488;5484:6;5480:14;5477:1;5474:21;5469:1;5462:9;5455:17;5451:45;5448:71;;;5499:18;;:::i;:::-;-1:-1:-1;5539:9:1;;5386:168::o;5848:135::-;5887:3;-1:-1:-1;;5908:17:1;;5905:43;;;5928:18;;:::i;:::-;-1:-1:-1;5975:1:1;5964:13;;5848:135::o;6993:128::-;7033:3;7064:1;7060:6;7057:1;7054:13;7051:39;;;7070:18;;:::i;:::-;-1:-1:-1;7106:9:1;;6993:128::o;7308:251::-;7378:6;7431:2;7419:9;7410:7;7406:23;7402:32;7399:52;;;7447:1;7444;7437:12;7399:52;7479:9;7473:16;7498:31;7523:5;7498:31;:::i;8590:127::-;8651:10;8646:3;8642:20;8639:1;8632:31;8682:4;8679:1;8672:15;8706:4;8703:1;8696:15;8722:461;8775:3;8813:5;8807:12;8840:6;8835:3;8828:19;8866:4;8895:2;8890:3;8886:12;8879:19;;8932:2;8925:5;8921:14;8953:1;8963:195;8977:6;8974:1;8971:13;8963:195;;;9042:13;;-1:-1:-1;;;;;9038:39:1;9026:52;;9098:12;;;;9133:15;;;;9074:1;8992:9;8963:195;;;-1:-1:-1;9174:3:1;;8722:461;-1:-1:-1;;;;;8722:461:1:o;9188:332::-;9395:6;9384:9;9377:25;9438:2;9433;9422:9;9418:18;9411:30;9358:4;9458:56;9510:2;9499:9;9495:18;9487:6;9458:56;:::i;9525:1105::-;9620:6;9651:2;9694;9682:9;9673:7;9669:23;9665:32;9662:52;;;9710:1;9707;9700:12;9662:52;9743:9;9737:16;9772:18;9813:2;9805:6;9802:14;9799:34;;;9829:1;9826;9819:12;9799:34;9867:6;9856:9;9852:22;9842:32;;9912:7;9905:4;9901:2;9897:13;9893:27;9883:55;;9934:1;9931;9924:12;9883:55;9963:2;9957:9;9985:2;9981;9978:10;9975:36;;;9991:18;;:::i;:::-;10037:2;10034:1;10030:10;10069:2;10063:9;10132:2;10128:7;10123:2;10119;10115:11;10111:25;10103:6;10099:38;10187:6;10175:10;10172:22;10167:2;10155:10;10152:18;10149:46;10146:72;;;10198:18;;:::i;:::-;10234:2;10227:22;10284:18;;;10318:15;;;;-1:-1:-1;10360:11:1;;;10356:20;;;10388:19;;;10385:39;;;10420:1;10417;10410:12;10385:39;10444:11;;;;10464:135;10480:6;10475:3;10472:15;10464:135;;;10546:10;;10534:23;;10497:12;;;;10577;;;;10464:135;;;10618:6;9525:1105;-1:-1:-1;;;;;;;;9525:1105:1:o;11811:274::-;11940:3;11978:6;11972:13;11994:53;12040:6;12035:3;12028:4;12020:6;12016:17;11994:53;:::i;:::-;12063:16;;;;;11811:274;-1:-1:-1;;11811:274:1:o;12090:127::-;12151:10;12146:3;12142:20;12139:1;12132:31;12182:4;12179:1;12172:15;12206:4;12203:1;12196:15;12618:574;12909:6;12898:9;12891:25;12952:6;12947:2;12936:9;12932:18;12925:34;12995:3;12990:2;12979:9;12975:18;12968:31;12872:4;13016:57;13068:3;13057:9;13053:19;13045:6;13016:57;:::i;:::-;-1:-1:-1;;;;;13109:32:1;;;;13104:2;13089:18;;13082:60;-1:-1:-1;13173:3:1;13158:19;13151:35;13008:65;12618:574;-1:-1:-1;;;12618:574:1:o
Swarm Source
ipfs://ec5f479a0eb5308519f8caa4a9b569b9dd6afb321e14c0a704a6d683e9aef649
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.