Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60e06040 | 16398034 | 563 days ago | IN | 0 ETH | 0.06258651 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19062943 | 189 days ago | 4.22581268 ETH | ||||
19062943 | 189 days ago | 4.22581038 ETH | ||||
19062943 | 189 days ago | 0.0000023 ETH | ||||
19062215 | 189 days ago | 1.18888631 ETH | ||||
19062215 | 189 days ago | 1.18887336 ETH | ||||
19012213 | 196 days ago | 0.00000371 ETH | ||||
18912512 | 210 days ago | 0.00000475 ETH | ||||
18812805 | 224 days ago | 0.00000448 ETH | ||||
18755148 | 232 days ago | 0.38373395 ETH | ||||
18755148 | 232 days ago | 0.38371804 ETH | ||||
18712930 | 238 days ago | 0.00000542 ETH | ||||
18612929 | 252 days ago | 0.00000492 ETH | ||||
18512870 | 266 days ago | 0.00000555 ETH | ||||
18446328 | 275 days ago | 0.51328767 ETH | ||||
18446328 | 275 days ago | 0.51328767 ETH | ||||
18413272 | 280 days ago | 2.88846422 ETH | ||||
18413272 | 280 days ago | 2.88845099 ETH | ||||
18412898 | 280 days ago | 0.00001323 ETH | ||||
18406000 | 281 days ago | 2.62732261 ETH | ||||
18406000 | 281 days ago | 2.62732261 ETH | ||||
18399080 | 282 days ago | 3.32624593 ETH | ||||
18399080 | 282 days ago | 3.32615968 ETH | ||||
18312845 | 294 days ago | 0.00002256 ETH | ||||
18212731 | 308 days ago | 0.00003691 ETH | ||||
18113042 | 322 days ago | 0.00000601 ETH |
Loading...
Loading
Contract Name:
MeroEthCvx
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-13 */ // Sources flattened with hardhat v2.6.1 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/[email protected] // SPDX-License-Identifier: GPL-3.0-or-later // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity 0.8.10; /** * @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/structs/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) /** * @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 @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) /** * @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) /** * @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 libraries/UncheckedMath.sol library UncheckedMath { function uncheckedInc(uint256 a) internal pure returns (uint256) { unchecked { return a + 1; } } function uncheckedAdd(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { return a + b; } } function uncheckedSub(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { return a - b; } } function uncheckedDiv(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { return a / b; } } } // File contracts/utils/CvxMintAmount.sol abstract contract CvxMintAmount { using UncheckedMath for uint256; uint256 private constant _CLIFF_SIZE = 100_000e18; //new cliff every 100,000 tokens uint256 private constant _CLIFF_COUNT = 1000; // 1,000 cliffs uint256 private constant _MAX_SUPPLY = 100_000_000e18; //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.uncheckedDiv(_CLIFF_SIZE); //if current cliff is under the max if (currentCliff >= _CLIFF_COUNT) return 0; //get remaining cliffs uint256 remaining = _CLIFF_COUNT.uncheckedSub(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 interfaces/IRoleManager.sol 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 initialize() external; function grantRole(bytes32 role, address account) external; function addGovernor(address newGovernor) external; function renounceGovernance() external; function addGaugeZap(address zap) external; function removeGaugeZap(address zap) 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 libraries/Errors.sol // 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 UNAUTHORIZED_PAUSE = "not authorized to pause"; 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_ALLOWANCE = "insufficient allowance"; string internal constant INSUFFICIENT_BALANCE = "insufficient balance"; string internal constant INSUFFICIENT_AMOUNT_OUT = "Amount received less than min amount"; string internal constant PROXY_CALL_FAILED = "proxy call failed"; string internal constant INSUFFICIENT_AMOUNT_IN = "Amount spent more than max amount"; 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 CANNOT_EXECUTE_IN_SAME_BLOCK = "cannot execute action in same block"; 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 NOTHING_PENDING = "no pending change to reset"; 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 must 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 ALREADY_SHUTDOWN = "already shutdown"; 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 GAUGE_KILLED = "gauge killed"; string internal constant INVALID_TARGET = "Invalid Target"; 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_SHUTDOWN = "Strategy is shutdown"; string internal constant POOL_SHUTDOWN = "Pool is shutdown"; string internal constant ACTION_SHUTDOWN = "Action is shutdown"; string internal constant ACTION_PAUSED = "Action is paused"; string internal constant STRATEGY_DOES_NOT_EXIST = "Strategy does not exist"; string internal constant GAUGE_STILL_ACTIVE = "Gauge still active"; 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 ACTION_NOT_ACTIVE = "address is not active action"; string internal constant INVALID_SLIPPAGE_TOLERANCE = "Invalid slippage tolerance"; string internal constant INVALID_MAX_FEE = "invalid max fee"; 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 ROUND_NOT_COMPLETE = "Round not complete"; string internal constant NOT_ENOUGH_MERO_STAKED = "Not enough MERO tokens staked"; string internal constant RESERVE_ACCESS_EXCEEDED = "Reserve access exceeded"; } // File libraries/Roles.sol // 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_ADMIN = "inflation_admin"; bytes32 internal constant INFLATION_MANAGER = "inflation_manager"; bytes32 internal constant POOL = "pool"; bytes32 internal constant VAULT = "vault"; bytes32 internal constant ACTION = "action"; } // File contracts/access/AuthorizationBase.sol /** * @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 contract Authorization is AuthorizationBase { IRoleManager internal immutable __roleManager; constructor(IRoleManager roleManager) { __roleManager = roleManager; } function _roleManager() internal view override returns (IRoleManager) { return __roleManager; } } // File libraries/ScaledMath.sol /* * @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 interfaces/IGasBank.sol 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 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; function withdraw(address token, uint256 amount) external; function getBalance(address vault, address token) external view returns (uint256); function canWithdraw(address vault) external view returns (bool); } // File interfaces/oracles/IOracleProvider.sol interface IOracleProvider { /// @notice Checks whether the asset is supported /// @param baseAsset the asset of which the price is to be quoted /// @return true if the asset is supported function isAssetSupported(address baseAsset) external view returns (bool); /// @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/strategies/IStrategy.sol interface IStrategy { function deposit() external payable returns (bool); function withdraw(uint256 amount) external returns (bool); function withdrawAll() external returns (uint256); function harvest() external returns (uint256); function shutdown() external; function setCommunityReserve(address _communityReserve) external; function setStrategist(address strategist_) external; function name() external view returns (string memory); function balance() external view returns (uint256); function harvestable() external view returns (uint256); function strategist() external view returns (address); function hasPendingFunds() external view returns (bool); } // File interfaces/IVault.sol /** * @title Interface for a Vault */ interface IVault { struct InitializationArgs { uint256 debtLimit; uint256 targetAllocation; uint256 bound; uint256 strategistFee; uint256 reserveFee; } event StrategyActivated(address indexed strategy); event StrategyDeactivated(address indexed strategy); event StrategyUpdated(address newStrategy); event PerformanceFeeUpdated(uint256 performanceFee); event StrategistFeeUpdated(uint256 strategistFee); event DebtLimitUpdated(uint256 debtLimit); event TargetAllocationUpdated(uint256 targetAllocation); event ReserveFeeUpdated(uint256 reserveFee); event BoundUpdated(uint256 bound); event AllFundsWithdrawn(); /** * @dev 'netProfit' is the profit after all fees have been deducted */ event Harvest(uint256 indexed netProfit, uint256 indexed loss); function initialize(address _pool, InitializationArgs memory args) external; function withdrawFromStrategyWaitingForRemoval(address strategy) external returns (uint256); function deposit() external payable; function withdraw(uint256 amount) external returns (bool); function withdrawAvailableToPool() external; function initializeStrategy(address strategy_) external; function shutdownStrategy() external; function withdrawFromReserve(uint256 amount) external; function updateStrategy(address newStrategy) external; function activateStrategy() external returns (bool); function deactivateStrategy() external returns (bool); function updatePerformanceFee(uint256 newPerformanceFee) external; function updateStrategistFee(uint256 newStrategistFee) external; function updateDebtLimit(uint256 newDebtLimit) external; function updateTargetAllocation(uint256 newTargetAllocation) external; function updateReserveFee(uint256 newReserveFee) external; function updateBound(uint256 newBound) external; function withdrawFromStrategy(uint256 amount) external returns (bool); function withdrawAllFromStrategy() external returns (bool); function harvest() external returns (bool); 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); function strategy() external view returns (IStrategy); } // File interfaces/IStakerVault.sol interface IStakerVault { event Staked(address indexed account, uint256 amount); event Unstaked(address indexed account, uint256 amount); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function initialize(address _token) external; function initializeLpGauge(address _lpGauge) external; function stake(uint256 amount) external; function stakeFor(address account, uint256 amount) external; function unstake(uint256 amount) external; function unstakeFor( address src, address dst, uint256 amount ) external; function approve(address spender, uint256 amount) external; function transfer(address account, uint256 amount) external; function transferFrom( address src, address dst, uint256 amount ) external; function increaseActionLockedBalance(address account, uint256 amount) external; function decreaseActionLockedBalance(address account, uint256 amount) external; function updateLpGauge(address _lpGauge) external; function poolCheckpoint() external returns (bool); function poolCheckpoint(uint256 updateEndTime) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function getToken() external view returns (address); function balanceOf(address account) external view returns (uint256); function stakedAndActionLockedBalanceOf(address account) external view returns (uint256); function actionLockedBalanceOf(address account) external view returns (uint256); function getStakedByActions() external view returns (uint256); function getPoolTotalStaked() external view returns (uint256); function decimals() external view returns (uint8); function lpGauge() external view returns (address); } // File interfaces/pool/ILiquidityPool.sol interface ILiquidityPool { struct InitializationArgs { string name; uint256 requiredReserves; uint256 reserveDeviation; uint256 maxWithdrawalFee; uint256 minWithdrawalFee; uint256 withdrawalFeeDecreasePeriod; } 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); event Shutdown(); event RequiredReservesUpdated(uint256 requireReserves); event ReserveDeviationUpdated(uint256 reserveDeviation); event MinWithdrawalFeeUpdated(uint256 minWithdrawalFee); event MaxWithdrawalFeeUpdated(uint256 maxWithdrawalFee); event WithdrawalFeeDecreasePeriodUpdated(uint256 withdrawalFeeDecreasePeriod); event VaultUpdated(address vault); 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 updateVault(address _vault) external; function setLpToken(address _lpToken) external; function setStaker() external; function shutdownPool(bool shutdownStrategy) external; function shutdownStrategy() external; function updateRequiredReserves(uint256 _newRatio) external; function updateReserveDeviation(uint256 newRatio) external; function updateMinWithdrawalFee(uint256 newFee) external; function updateMaxWithdrawalFee(uint256 newFee) external; function updateWithdrawalFeeDecreasePeriod(uint256 newPeriod) external; function rebalanceVault() external; function getNewCurrentFees( uint256 timeToWait, uint256 lastActionTimestamp, uint256 feeRatio ) external view returns (uint256); function vault() external view returns (IVault); function staker() external view returns (IStakerVault); function getUnderlying() external view returns (address); function getLpToken() external view returns (address); function getWithdrawalFee(address account, uint256 amount) external view returns (uint256); function exchangeRate() external view returns (uint256); function totalUnderlying() external view returns (uint256); function name() external view returns (string memory); function isShutdown() external view returns (bool); } // File libraries/AddressProviderMeta.sol 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 // solhint-disable ordering interface IAddressProvider { event KnownAddressKeyAdded(bytes32 indexed key); event StakerVaultListed(address indexed stakerVault); event StakerVaultDelisted(address indexed stakerVault); event ActionListed(address indexed action); event ActionShutdown(address indexed action); event PoolListed(address indexed pool); event VaultUpdated(address indexed previousVault, address indexed newVault); event FeeHandlerAdded(address feeHandler); event FeeHandlerRemoved(address feeHandler); /** 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 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 actionsCount() external view returns (uint256); function getActionAtIndex(uint256 index) external view returns (address); function allActiveActions() external view returns (address[] memory); function addAction(address action) external returns (bool); function shutdownAction(address action) external; function isAction(address action) external view returns (bool); function isActiveAction(address action) external view returns (bool); /** Address functions */ function initialize(address roleManager_, address treasury_) external; function initializeAddress(bytes32 key, address initialAddress) external; 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 updateAddress(bytes32 key, address newAddress) external; function initializeInflationManager(address initialAddress) external; /** 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; 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); /** Fee Handler function */ function addFeeHandler(address feeHandler) external; function removeFeeHandler(address feeHandler) external; } // File interfaces/IFeeBurner.sol interface IFeeBurner { function burnToTarget(address[] memory tokens, address targetLpToken) external payable returns (uint256); } // File interfaces/tokenomics/IMeroToken.sol interface IMeroToken is IERC20 { function mint(address account, uint256 amount) external; function cap() external view returns (uint256); } // File interfaces/actions/IAction.sol interface IAction { event UsableTokenAdded(address token); event UsableTokenRemoved(address token); event Paused(); event Unpaused(); event Shutdown(); function addUsableToken(address token) external; function addUsableToken(address token, bytes32 data) external; function removeUsableToken(address token) external; function updateActionFee(uint256 actionFee) external; function updateFeeHandler(address feeHandler) external; function shutdownAction() external; function pause() external; function unpause() external; function getEthRequiredForGas(address payer) external view returns (uint256); function getUsableTokens() external view returns (address[] memory); function isUsable(address token) external view returns (bool); function feeHandler() external view returns (address); function isShutdown() external view returns (bool); function isPaused() external view returns (bool); } // File interfaces/tokenomics/IInflationManager.sol 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 setMinter(address _minter) external; function advanceKeeperGaugeEpoch(address pool) external; function whitelistGauge(address gauge) external; function removeStakerVaultFromInflation(address lpToken) external; function removeAmmGauge(address token) external returns (bool); function addGaugeForVault(address lpToken) external; function checkpointAllGauges(uint256 updateEndTime) external; function mintRewards(address beneficiary, uint256 amount) external; function checkPointInflation() external; function removeKeeperGauge(address pool) external; 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 getLpPoolWeight(address pool) external view returns (uint256); function getKeeperGaugeForPool(address pool) external view returns (address); function getAmmGaugeForToken(address token) external view returns (address); function gauges(address lpToken) external view returns (bool); function ammWeights(address gauge) external view returns (uint256); function lpPoolWeights(address gauge) external view returns (uint256); function keeperPoolWeights(address gauge) external view returns (uint256); function minter() external view returns (address); function weightBasedKeeperDistributionDeactivated() external view returns (bool); function totalKeeperPoolWeight() external view returns (uint256); function totalLpPoolWeight() external view returns (uint256); function totalAmmTokenWeight() external view returns (uint256); /** Weight setter functions **/ function updateLpPoolWeight(address lpToken, uint256 newPoolWeight) external; function updateAmmTokenWeight(address token, uint256 newTokenWeight) external; function updateKeeperPoolWeight(address pool, uint256 newPoolWeight) external; function batchUpdateLpPoolWeights(address[] calldata lpTokens, uint256[] calldata weights) external; function batchUpdateAmmTokenWeights(address[] calldata tokens, uint256[] calldata weights) external; function batchUpdateKeeperPoolWeights(address[] calldata pools, uint256[] calldata weights) external; function deactivateWeightBasedKeeperDistribution() external; } // File interfaces/IController.sol // solhint-disable ordering interface IController { function addressProvider() external view returns (IAddressProvider); function addStakerVault(address stakerVault) external; function shutdownPool(ILiquidityPool pool, bool shutdownStrategy) external returns (bool); function shutdownAction(IAction action) external; /** Keeper functions */ function updateKeeperRequiredStakedMERO(uint256 amount) external; function canKeeperExecuteAction(address keeper) external view returns (bool); function keeperRequireStakedMero() external view returns (uint256); /** Miscellaneous functions */ function getTotalEthRequiredForGas(address payer) external view returns (uint256); } // File interfaces/ISwapperRouter.sol interface ISwapperRouter { function swapAll(address fromToken, address toToken) external payable returns (uint256); function setSlippageTolerance(uint256 slippageTolerance_) external; function setCurvePool(address token_, address curvePool_) external; function swap( address fromToken, address toToken, uint256 amountIn ) external payable returns (uint256); function getAmountOut( address fromToken, address toToken, uint256 amountIn ) external view returns (uint256 amountOut); } // File libraries/AddressProviderKeys.sol library AddressProviderKeys { bytes32 internal constant _TREASURY_KEY = "treasury"; bytes32 internal constant _REWARD_HANDLER_KEY = "rewardHandler"; bytes32 internal constant _GAS_BANK_KEY = "gasBank"; bytes32 internal constant _VAULT_RESERVE_KEY = "vaultReserve"; bytes32 internal constant _ORACLE_PROVIDER_KEY = "oracleProvider"; bytes32 internal constant _POOL_FACTORY_KEY = "poolFactory"; bytes32 internal constant _CONTROLLER_KEY = "controller"; bytes32 internal constant _MERO_LOCKER_KEY = "meroLocker"; bytes32 internal constant _INFLATION_MANAGER_KEY = "inflationManager"; bytes32 internal constant _FEE_BURNER_KEY = "feeBurner"; bytes32 internal constant _ROLE_MANAGER_KEY = "roleManager"; bytes32 internal constant _SWAPPER_ROUTER_KEY = "swapperRouter"; } // File libraries/AddressProviderHelpers.sol library AddressProviderHelpers { /** * @return The address of the treasury. */ function getTreasury(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._TREASURY_KEY); } /** * @return The address of the reward handler. */ function getRewardHandler(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._REWARD_HANDLER_KEY); } /** * @dev Returns zero address if no reward handler is set. * @return The address of the reward handler. */ function getSafeRewardHandler(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._REWARD_HANDLER_KEY, false); } /** * @return The address of the fee burner. */ function getFeeBurner(IAddressProvider provider) internal view returns (IFeeBurner) { return IFeeBurner(provider.getAddress(AddressProviderKeys._FEE_BURNER_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 oracleProvider. */ function getOracleProvider(IAddressProvider provider) internal view returns (IOracleProvider) { return IOracleProvider(provider.getAddress(AddressProviderKeys._ORACLE_PROVIDER_KEY)); } /** * @return the address of the MERO locker */ function getMEROLocker(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._MERO_LOCKER_KEY); } /** * @return the address of the MERO 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)); } /** * @return the inflation manager */ function getInflationManager(IAddressProvider provider) internal view returns (IInflationManager) { return IInflationManager(provider.getAddress(AddressProviderKeys._INFLATION_MANAGER_KEY)); } /** * @return the inflation manager or `address(0)` if it does not exist */ function safeGetInflationManager(IAddressProvider provider) internal view returns (IInflationManager) { return IInflationManager( provider.getAddress(AddressProviderKeys._INFLATION_MANAGER_KEY, false) ); } /** * @return the swapper router */ function getSwapperRouter(IAddressProvider provider) internal view returns (ISwapperRouter) { return ISwapperRouter(provider.getAddress(AddressProviderKeys._SWAPPER_ROUTER_KEY)); } } // File libraries/EnumerableMapping.sol library EnumerableMapping { using EnumerableSet for EnumerableSet.Bytes32Set; // Code take from contracts/utils/structs/EnumerableMap.sol // because the helper functions are private // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set( Map storage map, bytes32 key, bytes32 value ) private returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (_contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key"); return value; } // AddressToAddressMap struct AddressToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( AddressToAddressMap storage map, address key, address value ) internal returns (bool) { return _set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToAddressMap storage map, address key) internal returns (bool) { return _remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToAddressMap storage map, address key) internal view returns (bool) { return _contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element 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(AddressToAddressMap storage map, uint256 index) internal view returns (address, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (address(uint160(uint256(key))), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToAddressMap storage map, address key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(uint256(uint160(key))))))); } // AddressToUintMap struct AddressToUintMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( AddressToUintMap storage map, address key, uint256 value ) internal returns (bool) { return _set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToUintMap storage map, address key) internal returns (bool) { return _remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToUintMap storage map, address key) internal view returns (bool) { return _contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToUintMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element 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(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (address(uint160(uint256(key))), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToUintMap storage map, address key) internal view returns (uint256) { return uint256(_get(map._inner, bytes32(uint256(uint160(key))))); } // Bytes32ToUIntMap struct Bytes32ToUIntMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( Bytes32ToUIntMap storage map, bytes32 key, uint256 value ) internal returns (bool) { return _set(map._inner, key, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToUIntMap storage map, bytes32 key) internal returns (bool) { return _remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToUIntMap storage map, bytes32 key) internal view returns (bool) { return _contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToUIntMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element 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(Bytes32ToUIntMap storage map, uint256 index) internal view returns (bytes32, uint256) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (key, uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(Bytes32ToUIntMap storage map, bytes32 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = _tryGet(map._inner, key); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToUIntMap storage map, bytes32 key) internal view returns (uint256) { return uint256(_get(map._inner, key)); } } // File libraries/EnumerableExtensions.sol library EnumerableExtensions { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableMapping for EnumerableMapping.AddressToAddressMap; using EnumerableMapping for EnumerableMapping.AddressToUintMap; using EnumerableMapping for EnumerableMapping.Bytes32ToUIntMap; function toArray(EnumerableSet.AddressSet storage addresses) internal view returns (address[] memory) { uint256 len = addresses.length(); address[] memory result = new address[](len); for (uint256 i; i < len; ) { result[i] = addresses.at(i); unchecked { ++i; } } return result; } function toArray(EnumerableSet.Bytes32Set storage values) internal view returns (bytes32[] memory) { uint256 len = values.length(); bytes32[] memory result = new bytes32[](len); for (uint256 i; i < len; ) { result[i] = values.at(i); unchecked { ++i; } } return result; } function keyAt(EnumerableMapping.AddressToAddressMap storage map, uint256 index) internal view returns (address) { (address key, ) = map.at(index); return key; } function valueAt(EnumerableMapping.AddressToAddressMap storage map, uint256 index) internal view returns (address) { (, address value) = map.at(index); return value; } function keyAt(EnumerableMapping.AddressToUintMap storage map, uint256 index) internal view returns (address) { (address key, ) = map.at(index); return key; } function keyAt(EnumerableMapping.Bytes32ToUIntMap storage map, uint256 index) internal view returns (bytes32) { (bytes32 key, ) = map.at(index); return key; } function valueAt(EnumerableMapping.AddressToUintMap storage map, uint256 index) internal view returns (uint256) { (, uint256 value) = map.at(index); return value; } function keysArray(EnumerableMapping.AddressToAddressMap storage map) internal view returns (address[] memory) { uint256 len = map.length(); address[] memory result = new address[](len); for (uint256 i; i < len; ) { result[i] = keyAt(map, i); unchecked { ++i; } } return result; } function valuesArray(EnumerableMapping.AddressToAddressMap storage map) internal view returns (address[] memory) { uint256 len = map.length(); address[] memory result = new address[](len); for (uint256 i; i < len; ) { result[i] = valueAt(map, i); unchecked { ++i; } } return result; } function keysArray(EnumerableMapping.AddressToUintMap storage map) internal view returns (address[] memory) { uint256 len = map.length(); address[] memory result = new address[](len); for (uint256 i; i < len; ) { result[i] = keyAt(map, i); unchecked { ++i; } } return result; } function keysArray(EnumerableMapping.Bytes32ToUIntMap storage map) internal view returns (bytes32[] memory) { uint256 len = map.length(); bytes32[] memory result = new bytes32[](len); for (uint256 i; i < len; ) { result[i] = keyAt(map, i); unchecked { ++i; } } return result; } } // File interfaces/strategies/IConvexStrategyBase.sol interface IConvexStrategyBase is IStrategy { function setCrvCommunityReserveShare(uint256 crvCommunityReserveShare_) external; function setCvxCommunityReserveShare(uint256 cvxCommunityReserveShare_) external; function setImbalanceToleranceIn(uint256 imbalanceToleranceIn_) external; function setImbalanceToleranceOut(uint256 imbalanceToleranceOut_) external; function addRewardToken(address token_) external returns (bool); function removeRewardToken(address token_) external returns (bool); function rewardTokens() external view returns (address[] memory); } // File interfaces/vendor/IBooster.sol interface IBooster { /** * @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 withdrawTo( uint256 _pid, uint256 _amount, address _to ) external returns (bool); function depositAll(uint256 _pid, bool _stake) external returns (bool); function poolInfo(uint256 pid) external view returns ( address lpToken, address token, address gauge, address crvRewards, address stash, bool shutdown ); } // File interfaces/vendor/IRewardStaking.sol 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/ICurveSwapEth.sol interface ICurveSwapEth { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[2] calldata amounts, uint256 min_mint_amount) external payable; function add_liquidity(uint256[3] 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/ICurveRegistry.sol interface ICurveRegistry { function get_A(address curvePool_) external view returns (uint256); } // File contracts/strategies/ConvexStrategyBase.sol abstract contract ConvexStrategyBase is IConvexStrategyBase, Authorization, CvxMintAmount { using ScaledMath for uint256; using UncheckedMath for uint256; using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; using EnumerableExtensions for EnumerableSet.AddressSet; using AddressProviderHelpers for IAddressProvider; IBooster internal constant _BOOSTER = IBooster(0xF403C135812408BFbE8713b5A23a04b3D48AAE31); // Convex Booster Contract IERC20 internal constant _CRV = IERC20(0xD533a949740bb3306d119CC777fa900bA034cd52); // CRV IERC20 internal constant _CVX = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); // CVX IERC20 internal constant _WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); // WETH ICurveRegistry internal constant _CURVE_REGISTRY = ICurveRegistry(0x90E00ACe148ca3b23Ac1bC8C240C2a7Dd9c2d7f5); // Curve Registry Contract address internal constant _CURVE_ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); // Null Address used for Curve ETH pools IAddressProvider internal immutable _addressProvider; // Address Provider, used for getting Swapper Router address internal _strategist; // The strategist for the strategy EnumerableSet.AddressSet internal _rewardTokens; // List of additional reward tokens when claiming rewards on Convex IERC20 public underlying; // Strategy Underlying bool public isShutdown; // If the strategy is shutdown, stops all deposits address public communityReserve; // Address for sending CVX & CRV Community Reserve share address public immutable vault; // Mero Vault uint256 public crvCommunityReserveShare; // Share of CRV sent to Community Reserve uint256 public cvxCommunityReserveShare; // Share of CVX sent to Community Reserve uint256 public imbalanceToleranceIn; // Maximum allowed slippage from Curve Pool Imbalance for depositing uint256 public imbalanceToleranceOut; // Maximum allowed slippage from Curve Pool Imbalance for withdrawing IRewardStaking public rewards; // Rewards Contract for claiming Convex Rewards IERC20 public lp; // Curve Pool LP Token ICurveSwapEth public curvePool; // Curve Pool uint256 public convexPid; // Index of Convex Pool in Booster Contract uint256 public curveIndex; // Underlying index in Curve Pool event Deposit(); // Emitted after a successfull deposit event Withdraw(uint256 amount); // Emitted after a successful withdrawal event WithdrawAll(uint256 amount); // Emitted after successfully withdrwaing all event Shutdown(); // Emitted after a successful shutdown event SetCommunityReserve(address reserve); // Emitted after a successful setting of reserve event SetCrvCommunityReserveShare(uint256 value); // Emitted after a successful setting of CRV Community Reserve Share event SetCvxCommunityReserveShare(uint256 value); // Emitted after a successful setting of CVX Community Reserve Share event SetImbalanceToleranceIn(uint256 value); // Emitted after a successful setting of imbalance tolerance in event SetImbalanceToleranceOut(uint256 value); // Emitted after a successful setting of imbalance tolerance out event SetStrategist(address strategist); // Emitted after a successful 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 Harvest(uint256 amount); // Emitted after a successful harvest modifier onlyVault() { require(msg.sender == vault, Error.UNAUTHORIZED_ACCESS); _; } constructor( address vault_, address strategist_, uint256 convexPid_, address curvePool_, uint256 curveIndex_, IAddressProvider addressProvider_ ) Authorization(addressProvider_.getRoleManager()) { // Getting data from supporting contracts _validateCurvePool(curvePool_); (address lp_, , , address rewards_, , bool shutdown_) = _BOOSTER.poolInfo(convexPid_); require(!shutdown_, Error.POOL_SHUTDOWN); lp = IERC20(lp_); rewards = IRewardStaking(rewards_); curvePool = ICurveSwapEth(curvePool_); address underlying_ = ICurveSwapEth(curvePool_).coins(curveIndex_); if (underlying_ == _CURVE_ETH_ADDRESS) underlying_ = address(0); underlying = IERC20(underlying_); // Setting inputs vault = vault_; _strategist = strategist_; convexPid = convexPid_; curveIndex = curveIndex_; _addressProvider = addressProvider_; ISwapperRouter swapperRouter_ = addressProvider_.getSwapperRouter(); // Approvals _CRV.safeApprove(address(swapperRouter_), type(uint256).max); _CVX.safeApprove(address(swapperRouter_), type(uint256).max); _WETH.safeApprove(address(swapperRouter_), type(uint256).max); } /** * @notice Deposit all available underlying into Convex pool. * @return True if successful deposit. */ function deposit() external payable override onlyVault returns (bool) { require(!isShutdown, Error.STRATEGY_SHUTDOWN); if (!_deposit()) return false; emit Deposit(); } /** * @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; _withdraw(amount_); emit Withdraw(amount_); return true; } /** * @notice Withdraw all underlying. * @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, Error.UNAUTHORIZED_ACCESS); uint256 amountWithdrawn_ = _withdrawAll(); if (amountWithdrawn_ == 0) return 0; emit WithdrawAll(amountWithdrawn_); return amountWithdrawn_; } /** * @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) { return _harvest(); } /** * @notice Shuts down the strategy, disabling deposits. */ function shutdown() external override onlyVault { require(!isShutdown, Error.STRATEGY_SHUTDOWN); isShutdown = true; emit Shutdown(); } /** * @notice Set the address of the community reserve. * @dev CRV & CVX will be taxed and allocated to the reserve, * such that Mero can participate in governance. * @param _communityReserve Address of the community reserve. */ function setCommunityReserve(address _communityReserve) external override onlyGovernance { require(_communityReserve != address(0), Error.ZERO_ADDRESS_NOT_ALLOWED); communityReserve = _communityReserve; emit SetCommunityReserve(_communityReserve); } /** * @notice Set the share of CRV to send to the Community Reserve. * @param crvCommunityReserveShare_ New fee charged on CRV rewards for governance. */ function setCrvCommunityReserveShare(uint256 crvCommunityReserveShare_) external override onlyGovernance { require(crvCommunityReserveShare_ <= ScaledMath.ONE, Error.INVALID_AMOUNT); require(communityReserve != address(0), "Community reserve must be set"); crvCommunityReserveShare = crvCommunityReserveShare_; emit SetCrvCommunityReserveShare(crvCommunityReserveShare_); } /** * @notice Set the share of CVX to send to the Community Reserve. * @param cvxCommunityReserveShare_ New fee charged on CVX rewards for governance. */ function setCvxCommunityReserveShare(uint256 cvxCommunityReserveShare_) external override onlyGovernance { require(cvxCommunityReserveShare_ <= ScaledMath.ONE, Error.INVALID_AMOUNT); require(communityReserve != address(0), "Community reserve must be set"); cvxCommunityReserveShare = cvxCommunityReserveShare_; emit SetCvxCommunityReserveShare(cvxCommunityReserveShare_); } /** * @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 tolerance in. */ function setImbalanceToleranceIn(uint256 imbalanceToleranceIn_) external override onlyGovernance { imbalanceToleranceIn = imbalanceToleranceIn_; emit SetImbalanceToleranceIn(imbalanceToleranceIn_); } /** * @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 tolerance out. */ function setImbalanceToleranceOut(uint256 imbalanceToleranceOut_) external override onlyGovernance { imbalanceToleranceOut = imbalanceToleranceOut_; emit SetImbalanceToleranceOut(imbalanceToleranceOut_); } /** * @notice Set strategist. * @dev Can only be set by current strategist. * @param strategist_ Address of new strategist. */ function setStrategist(address strategist_) external override { require(msg.sender == _strategist, Error.UNAUTHORIZED_ACCESS); _strategist = strategist_; emit SetStrategist(strategist_); } /** * @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 override onlyGovernance returns (bool) { require( token_ != address(_CVX) && token_ != address(underlying) && token_ != address(_CRV), Error.INVALID_TOKEN_TO_ADD ); if (_rewardTokens.contains(token_)) return false; _rewardTokens.add(token_); address swapperRouter_ = address(_swapperRouter()); IERC20(token_).safeApprove(swapperRouter_, 0); IERC20(token_).safeApprove(swapperRouter_, 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 override onlyGovernance returns (bool) { if (!_rewardTokens.remove(token_)) return false; emit RemoveRewardToken(token_); return true; } /** * @notice Amount of rewards that can be harvested in the underlying. * @dev Includes rewards for CRV, CVX & Extra Rewards. * @return Estimated amount of underlying available to harvest. */ function harvestable() external view override returns (uint256) { IRewardStaking rewards_ = rewards; uint256 crvAmount_ = rewards_.earned(address(this)); if (crvAmount_ == 0) return 0; uint256 harvestable_ = _underlyingAmountOut( address(_CRV), crvAmount_.scaledMul(ScaledMath.ONE - crvCommunityReserveShare) ) + _underlyingAmountOut( address(_CVX), getCvxMintAmount(crvAmount_).scaledMul(ScaledMath.ONE - cvxCommunityReserveShare) ); uint256 length_ = _rewardTokens.length(); for (uint256 i; i < length_; i = i.uncheckedInc()) { IRewardStaking extraRewards_ = IRewardStaking(rewards_.extraRewards(i)); address rewardToken_ = extraRewards_.rewardToken(); if (!_rewardTokens.contains(rewardToken_)) continue; harvestable_ += _underlyingAmountOut(rewardToken_, extraRewards_.earned(address(this))); } return harvestable_; } /** * @notice Returns the address of the strategist. * @return The the address of the strategist. */ function strategist() external view override returns (address) { return _strategist; } /** * @notice Returns the list of reward tokens supported by the strategy. * @return The list of reward tokens supported by the strategy. */ function rewardTokens() external view override returns (address[] memory) { return _rewardTokens.toArray(); } /** * @notice Get the total underlying balance of the strategy. * @return Underlying balance of strategy. */ function balance() external view virtual override returns (uint256); /** * @notice Returns the name of the strategy. * @return The name of the strategy. */ function name() external view virtual override returns (string memory); /** * @dev Contract does not stash tokens. */ function hasPendingFunds() external pure override returns (bool) { return false; } function _deposit() internal virtual returns (bool); function _withdraw(uint256 amount_) internal virtual; function _withdrawAll() internal virtual returns (uint256); function _harvest() internal returns (uint256) { uint256 initialBalance_ = _underlyingBalance(); // Claim Convex rewards rewards.getReward(); // Sending share to Community Reserve _sendCommunityReserveShare(); // Swap CVX for WETH ISwapperRouter swapperRouter_ = _swapperRouter(); swapperRouter_.swapAll(address(_CVX), address(_WETH)); // Swap CRV for WETH swapperRouter_.swapAll(address(_CRV), address(_WETH)); // Swap Extra Rewards for WETH uint256 length_ = _rewardTokens.length(); for (uint256 i; i < length_; i = i.uncheckedInc()) { swapperRouter_.swapAll(_rewardTokens.at(i), address(_WETH)); } // Swap WETH for underlying swapperRouter_.swapAll(address(_WETH), address(underlying)); uint256 harvested_ = _underlyingBalance() - initialBalance_; emit Harvest(harvested_); return harvested_; } /** * @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) { IERC20 cvx_ = _CVX; uint256 cvxBalance_ = cvx_.balanceOf(address(this)); if (cvxBalance_ > 0) { cvx_.safeTransfer( communityReserve_, cvxBalance_.scaledMul(cvxCommunityReserveShare_) ); } } uint256 crvCommunityReserveShare_ = crvCommunityReserveShare; if (crvCommunityReserveShare_ > 0) { IERC20 crv_ = _CRV; 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 virtual returns (uint256); /** * @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)); } function _underlyingAmountOut(address token_, uint256 amount_) internal view returns (uint256) { return _swapperRouter().getAmountOut(token_, address(underlying), amount_); } /** * @dev Reverts if it is not a valid Curve Pool. */ function _validateCurvePool(address curvePool_) internal view { _CURVE_REGISTRY.get_A(curvePool_); } /** * @dev Gets the Swapper Router, used for swapping tokens. */ function _swapperRouter() internal view returns (ISwapperRouter) { return _addressProvider.getSwapperRouter(); } } // File contracts/strategies/MeroEthCvx.sol /** * This is the MeroEthCvx strategy, which is designed to be used by a Mero 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 Mero community to participate in governance. */ contract MeroEthCvx is ConvexStrategyBase { using ScaledMath for uint256; using UncheckedMath for uint256; using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; using AddressProviderHelpers for IAddressProvider; constructor( address vault_, address strategist_, uint256 convexPid_, address curvePool_, uint256 curveIndex_, IAddressProvider addressProvider_ ) ConvexStrategyBase( vault_, strategist_, convexPid_, curvePool_, curveIndex_, addressProvider_ ) { // Setting default values imbalanceToleranceIn = 0.0007e18; imbalanceToleranceOut = 0.025e18; // Approvals (address lp_, , , , , bool shutdown) = _BOOSTER.poolInfo(convexPid_); require(!shutdown, Error.POOL_SHUTDOWN); IERC20(lp_).safeApprove(address(_BOOSTER), type(uint256).max); } receive() external payable {} function name() external pure override returns (string memory) { return "MeroEthCvx"; } function balance() public view override returns (uint256) { return _underlyingBalance() + _lpToUnderlying(_stakedBalance() + _lpBalance()); } function _deposit() internal override returns (bool) { // 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; return true; } function _withdraw(uint256 amount) internal override { bool success; uint256 underlyingBalance = _underlyingBalance(); // Transferring from idle balance if enough if (underlyingBalance >= amount) { // solhint-disable-next-line avoid-low-level-calls (success, ) = payable(vault).call{value: amount}(""); require(success, Error.FAILED_TRANSFER); return; } // Unstaking needed LP Tokens from Convex uint256 requiredUnderlyingAmount = amount.uncheckedSub(underlyingBalance); uint256 maxLpBurned = _maxLpBurned(requiredUnderlyingAmount); uint256 requiredLpAmount = maxLpBurned - _lpBalance(); if (!rewards.withdrawAndUnwrap(requiredLpAmount, false)) return; // Removing needed liquidity from Curve uint256[2] memory amounts; // solhint-disable-next-line reentrancy amounts[curveIndex] = requiredUnderlyingAmount; curvePool.remove_liquidity_imbalance(amounts, maxLpBurned); // solhint-disable-next-line avoid-low-level-calls (success, ) = payable(vault).call{value: amount}(""); require(success, Error.FAILED_TRANSFER); return; } function _withdrawAll() internal override returns (uint256) { // 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; // solhint-disable-next-line avoid-low-level-calls (bool success, ) = payable(vault).call{value: underlyingBalance}(""); require(success, Error.FAILED_TRANSFER); return underlyingBalance; } function _underlyingBalance() internal view override returns (uint256) { return address(this).balance; } /** * @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 withdrawn 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 susceptible 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 susceptible 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":"uint256","name":"convexPid_","type":"uint256"},{"internalType":"address","name":"curvePool_","type":"address"},{"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":[],"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":"address","name":"strategist","type":"address"}],"name":"SetStrategist","type":"event"},{"anonymous":false,"inputs":[],"name":"Shutdown","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":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"name":"removeRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","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":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"crvCommunityReserveShare_","type":"uint256"}],"name":"setCrvCommunityReserveShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cvxCommunityReserveShare_","type":"uint256"}],"name":"setCvxCommunityReserveShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"imbalanceToleranceIn_","type":"uint256"}],"name":"setImbalanceToleranceIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"imbalanceToleranceOut_","type":"uint256"}],"name":"setImbalanceToleranceOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategist_","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","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
60e06040523480156200001157600080fd5b5060405162003cc138038062003cc1833981016040819052620000349162000963565b85858585858562000059816001600160a01b03166200044260201b620019591760201c565b6001600160a01b03166080526200007083620004c5565b604051631526fe2760e01b8152600481018590526000908190819073f403c135812408bfbe8713b5a23a04b3d48aae3190631526fe279060240160c060405180830381865afa158015620000c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ee9190620009f5565b95505094505050925080156040518060400160405280601081526020016f2837b7b61034b99039b43aba3237bbb760811b815250906200014c5760405162461bcd60e51b815260040162000143919062000ab7565b60405180910390fd5b50600a80546001600160a01b038581166001600160a01b03199283161790925560098054858416908316179055600b8054928916929091168217905560405163c661065760e01b8152600481018790526000919063c661065790602401602060405180830381865afa158015620001c7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ed919062000aec565b90506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141562000219575060005b600380546001600160a01b03199081166001600160a01b03848116919091179092558b821660c052600080549091168b8316178155600c8a9055600d88905590861660a0819052620002779062000548602090811b620019d917901c565b9050620002a873d533a949740bb3306d119cc777fa900ba034cd528260001962000588602090811b62001a1817901c565b620002d7734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b8260001962000588602090811b62001a1817901c565b6200030673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28260001962000588602090811b62001a1817901c565b505066027ca57357c00060075550506658d15e176280006008555050604051631526fe2760e01b8152600481018a90526000955085945073f403c135812408bfbe8713b5a23a04b3d48aae319350631526fe279250602401905060c060405180830381865afa1580156200037e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a49190620009f5565b955050505050915080156040518060400160405280601081526020016f2837b7b61034b99039b43aba3237bbb760811b81525090620003f85760405162461bcd60e51b815260040162000143919062000ab7565b506200043473f403c135812408bfbe8713b5a23a04b3d48aae31600019846001600160a01b03166200058860201b62001a18179092919060201c565b505050505050505062000b62565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa15801562000499573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004bf919062000aec565b92915050565b6040516355b30b1960e01b81526001600160a01b03821660048201527390e00ace148ca3b23ac1bc8c240c2a7dd9c2d7f5906355b30b1990602401602060405180830381865afa1580156200051e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000544919062000b0c565b5050565b6040516321f8a72160e01b81526c39bbb0b83832b92937baba32b960991b60048201526000906001600160a01b038316906321f8a721906024016200047b565b801580620006065750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015620005de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000604919062000b0c565b155b6200067a5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840162000143565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620006d2918591620006d716565b505050565b600062000733826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620007b560201b62001b65179092919060201c565b805190915015620006d2578080602001905181019062000754919062000b26565b620006d25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000143565b6060620007c68484600085620007d0565b90505b9392505050565b606082471015620008335760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000143565b6001600160a01b0385163b6200088c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000143565b600080866001600160a01b03168587604051620008aa919062000b44565b60006040518083038185875af1925050503d8060008114620008e9576040519150601f19603f3d011682016040523d82523d6000602084013e620008ee565b606091505b509092509050620009018282866200090c565b979650505050505050565b606083156200091d575081620007c9565b8251156200092e5782518084602001fd5b8160405162461bcd60e51b815260040162000143919062000ab7565b6001600160a01b03811681146200096057600080fd5b50565b60008060008060008060c087890312156200097d57600080fd5b86516200098a816200094a565b60208801519096506200099d816200094a565b604088015160608901519196509450620009b7816200094a565b608088015160a08901519194509250620009d1816200094a565b809150509295509295509295565b80518015158114620009f057600080fd5b919050565b60008060008060008060c0878903121562000a0f57600080fd5b865162000a1c816200094a565b602088015190965062000a2f816200094a565b604088015190955062000a42816200094a565b606088015190945062000a55816200094a565b608088015190935062000a68816200094a565b915062000a7860a08801620009df565b90509295509295509295565b60005b8381101562000aa157818101518382015260200162000a87565b8381111562000ab1576000848401525b50505050565b602081526000825180602084015262000ad881604085016020870162000a84565b601f01601f19169190910160400192915050565b60006020828403121562000aff57600080fd5b8151620007c9816200094a565b60006020828403121562000b1f57600080fd5b5051919050565b60006020828403121562000b3957600080fd5b620007c982620009df565b6000825162000b5881846020870162000a84565b9190910192915050565b60805160a05160c0516130c662000bfb600039600081816105de015281816108aa01528181610b9301528181610ee4015281816112060152818161188401528181611bde01528181611dc6015261232e01526000611b9a0152600081816102170152818161063401528181610a3401528181610bdc01528181610cf901528181610fb001528181611586015261169c01526130c66000f3fe6080604052600436106101fc5760003560e01c80637bdcdaff1161010d578063c2bddf31116100a0578063e9eb50881161006f578063e9eb50881461058c578063ecf8db0a146105ac578063fbfa77cf146105cc578063fc0e74d114610600578063ff0af85b1461061557600080fd5b8063c2bddf311461052f578063c7b9d5301461054f578063d0e30db01461056f578063dbbd47d41461057757600080fd5b80639ec5a894116100dc5780639ec5a894146104b7578063b69ef8a8146104d7578063bf86d690146104ec578063c2b18aa01461050d57600080fd5b80637bdcdaff14610460578063853828b61461047657806386993bef1461048b5780639b61a924146104a157600080fd5b80633778851e1161019057806356be5f711161015f57806356be5f71146103d657806361240eea146103ec578063621e8fe1146104005780636f307dc31461042057806370aa17261461044057600080fd5b80633778851e1461035f5780633d509c971461037f5780634641257d1461039f57806349cabcdf146103b457600080fd5b80631fe4a686116101cc5780631fe4a686146102e1578063218751b2146102ff5780632e1a7d4d1461031f578063313c06a01461033f57600080fd5b8062435da51461020857806306fdde03146102545780631a55820d1461028d5780631c03e6cc146102b157600080fd5b3661020357005b600080fd5b34801561021457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b34801561026057600080fd5b50604080518082018252600a81526909acae4de8ae8d086ecf60b31b6020820152905161024b9190612e18565b34801561029957600080fd5b506102a360085481565b60405190815260200161024b565b3480156102bd57600080fd5b506102d16102cc366004612e63565b610630565b604051901515815260200161024b565b3480156102ed57600080fd5b506000546001600160a01b0316610237565b34801561030b57600080fd5b50600b54610237906001600160a01b031681565b34801561032b57600080fd5b506102d161033a366004612e80565b61087a565b34801561034b57600080fd5b50600a54610237906001600160a01b031681565b34801561036b57600080fd5b506102a361037a366004612e80565b61093b565b34801561038b57600080fd5b506102d161039a366004612e63565b610a30565b3480156103ab57600080fd5b506102a3610b63565b3480156103c057600080fd5b506103d46103cf366004612e80565b610bda565b005b3480156103e257600080fd5b506102a360075481565b3480156103f857600080fd5b5060006102d1565b34801561040c57600080fd5b50600454610237906001600160a01b031681565b34801561042c57600080fd5b50600354610237906001600160a01b031681565b34801561044c57600080fd5b506103d461045b366004612e80565b610cf7565b34801561046c57600080fd5b506102a3600d5481565b34801561048257600080fd5b506102a3610eb4565b34801561049757600080fd5b506102a3600c5481565b3480156104ad57600080fd5b506102a360065481565b3480156104c357600080fd5b50600954610237906001600160a01b031681565b3480156104e357600080fd5b506102a3610f74565b3480156104f857600080fd5b506003546102d190600160a01b900460ff1681565b34801561051957600080fd5b50610522610fa2565b60405161024b9190612e99565b34801561053b57600080fd5b506103d461054a366004612e63565b610fae565b34801561055b57600080fd5b506103d461056a366004612e63565b611139565b6102d16111d6565b34801561058357600080fd5b506102a36112db565b34801561059857600080fd5b506103d46105a7366004612e80565b611584565b3480156105b857600080fd5b506103d46105c7366004612e80565b61169a565b3480156105d857600080fd5b506102377f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c57600080fd5b506103d4611857565b34801561062157600080fd5b506102a360055481565b905090565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156106ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d09190612ee6565b6040518060400160405280601381526020016000805160206130718339815191528152509061071b5760405162461bcd60e51b81526004016107129190612e18565b60405180910390fd5b506001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b1480159061075757506003546001600160a01b03838116911614155b801561078057506001600160a01b03821673d533a949740bb3306d119cc777fa900ba034cd5214155b60405180604001604052806014815260200173125b9d985b1a59081d1bdad95b881d1bc818591960621b815250906107cb5760405162461bcd60e51b81526004016107129190612e18565b506001600160a01b038216600090815260026020526040902054156107f257506000919050565b6107fd600183611b7e565b506000610808611b93565b905061081f6001600160a01b038416826000611a18565b6108356001600160a01b03841682600019611a18565b6040516001600160a01b03841681527f851bbb4304bf0768ed98b97e429b5bd1dcc1f194b36cd1650f40293e951ae3939060200160405180910390a150600192915050565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108e85760405162461bcd60e51b81526004016107129190612e18565b50816108f657506000919050565b6108ff82611bc7565b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a1506001919050565b600080734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b49190612f08565b905060006109cc8269152d02c7e14af6800000611e7c565b90506103e881106109e1575060009392505050565b6103e8818103906000906109f58388612f37565b6109ff9190612f6c565b90506000610a18856a52b7d2dcc80cd2e4000000612f8e565b905080821115610a26578091505b5095945050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190612ee6565b60405180604001604052806013815260200160008051602061307183398151915281525090610b125760405162461bcd60e51b81526004016107129190612e18565b50610b1e600183611e95565b610b2a57506000919050565b6040516001600160a01b03831681527f36bd04094fa067bb9471a8fbdb0a6e8a43424a2566ad3a740c88973fa40a31189060200161092b565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bd15760405162461bcd60e51b81526004016107129190612e18565b5061062b611eaa565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c789190612ee6565b60405180604001604052806013815260200160008051602061307183398151915281525090610cba5760405162461bcd60e51b81526004016107129190612e18565b5060078190556040518181527f4ede3e4e9f7997fda6ff4a12d6c43d5c9e1e2055065cbc15f902f504f72dc8c0906020015b60405180910390a150565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d959190612ee6565b60405180604001604052806013815260200160008051602061307183398151915281525090610dd75760405162461bcd60e51b81526004016107129190612e18565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a7640000821115610e265760405162461bcd60e51b81526004016107129190612e18565b506004546001600160a01b0316610e7f5760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d757374206265207365740000006044820152606401610712565b60058190556040518181527f1a8542dffa4956932e66916113e6a123e123956172fbc0e2e59df92b8a87d8e690602001610cec565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f225760405162461bcd60e51b81526004016107129190612e18565b506000610f2d6121ee565b905080610f3c57600091505090565b6040518181527f3d5a341dc6a12221fcf31279cef3771f8fad757b2d9261f97605ccc17c2574249060200160405180910390a1919050565b6000610f98610f816123e7565b610f89612455565b610f939190612fa5565b612486565b61062b9047612fa5565b606061062b6001612509565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611028573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104c9190612ee6565b6040518060400160405280601381526020016000805160206130718339815191528152509061108e5760405162461bcd60e51b81526004016107129190612e18565b5060408051808201909152601881527f7a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060208201526001600160a01b0382166110ea5760405162461bcd60e51b81526004016107129190612e18565b50600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f17d7ba6682f162782054b119192f8e5b98fe7090b4bec7a55fc7075d9cd859ee90602001610cec565b60005460408051808201909152601381526000805160206130718339815191526020820152906001600160a01b031633146111875760405162461bcd60e51b81526004016107129190612e18565b50600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f46d58e3fa07bf19b1d27240f0e286b27e9f7c1b0d88933333fe833b60eec541290602001610cec565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112445760405162461bcd60e51b81526004016107129190612e18565b5060035460408051808201909152601481527329ba3930ba32b3bc9034b99039b43aba3237bbb760611b602082015290600160a01b900460ff161561129c5760405162461bcd60e51b81526004016107129190612e18565b506112a56125ae565b6112af5750600090565b6040517fed21248cb703b524cc0029bb8669df941baca560163a3bc6ad184e7e9c26807090600090a190565b6009546040516246613160e11b81523060048201526000916001600160a01b03169082908290628cc26290602401602060405180830381865afa158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190612f08565b90508061135a5760009250505090565b60006113a1734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b61139c600654670de0b6b3a764000061138d9190612f8e565b6113968661093b565b906126e3565b612702565b6113d973d533a949740bb3306d119cc777fa900ba034cd5261139c600554670de0b6b3a76400006113d29190612f8e565b86906126e3565b6113e39190612fa5565b905060006113f16001612788565b905060005b8181101561157a57604051632061aa2360e11b8152600481018290526000906001600160a01b038716906340c3544690602401602060405180830381865afa158015611446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146a9190612fbd565b90506000816001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d09190612fbd565b6001600160a01b0381166000908152600260205260409020549091506114f7575050611572565b6040516246613160e11b81523060048201526115639082906001600160a01b03851690628cc26290602401602060405180830381865afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190612f08565b61156d9086612fa5565b945050505b6001016113f6565b5090949350505050565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116229190612ee6565b604051806040016040528060138152602001600080516020613071833981519152815250906116645760405162461bcd60e51b81526004016107129190612e18565b5060088190556040518181527fb2861fed34a4613f8f25f46553a23408a3364ee9ddc4ef6714f0a81d856e41a790602001610cec565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611714573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117389190612ee6565b6040518060400160405280601381526020016000805160206130718339815191528152509061177a5760405162461bcd60e51b81526004016107129190612e18565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a76400008211156117c95760405162461bcd60e51b81526004016107129190612e18565b506004546001600160a01b03166118225760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d757374206265207365740000006044820152606401610712565b60068190556040518181527f2c3c7d70a1dfbfaf74447753b8a73e1323aa10b32b9209742db563671e14b13c90602001610cec565b60408051808201909152601381526000805160206130718339815191526020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146118c25760405162461bcd60e51b81526004016107129190612e18565b5060035460408051808201909152601481527329ba3930ba32b3bc9034b99039b43aba3237bbb760611b602082015290600160a01b900460ff161561191a5760405162461bcd60e51b81526004016107129190612e18565b506003805460ff60a01b1916600160a01b1790556040517f4426aa1fb73e391071491fcfe21a88b5c38a0a0333a1f6e77161470439704cf890600090a1565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa1580156119af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d39190612fbd565b92915050565b6040516321f8a72160e01b81526c39bbb0b83832b92937baba32b960991b60048201526000906001600160a01b038316906321f8a72190602401611992565b801580611a925750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190612f08565b155b611afd5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610712565b6040516001600160a01b038316602482015260448101829052611b6090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612792565b505050565b6060611b748484600085612864565b90505b9392505050565b6000611b77836001600160a01b038416612995565b600061062b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166119d9565b600047828110611c8e576040516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908490600081818185875af1925050503d8060008114611c3a576040519150601f19603f3d011682016040523d82523d6000602084013e611c3f565b606091505b505060408051808201909152600f81526e1d1c985b9cd9995c8819985a5b1959608a1b602082015290925082611c885760405162461bcd60e51b81526004016107129190612e18565b50505050565b8083036000611c9c826129e4565b90506000611ca86123e7565b611cb29083612f8e565b600954604051636197390160e11b815260048101839052600060248201529192506001600160a01b03169063c32e7202906044016020604051808303816000875af1158015611d05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d299190612ee6565b611d3557505050505050565b611d3d612dce565b8381600d5460028110611d5257611d52612fda565b6020020152600b5460405163e310327360e01b81526001600160a01b039091169063e310327390611d899084908790600401612ff0565b600060405180830381600087803b158015611da357600080fd5b505af1158015611db7573d6000803e3d6000fd5b50506040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250899150600081818185875af1925050503d8060008114611e24576040519150601f19603f3d011682016040523d82523d6000602084013e611e29565b606091505b505060408051808201909152600f81526e1d1c985b9cd9995c8819985a5b1959608a1b602082015290965086611e725760405162461bcd60e51b81526004016107129190612e18565b5050505050505050565b6000818381611e8d57611e8d612f56565b049392505050565b6000611b77836001600160a01b038416612a08565b60095460408051631e8c5c8960e11b8152905160009247926001600160a01b0390911691633d18b91291600480820192879290919082900301818387803b158015611ef457600080fd5b505af1158015611f08573d6000803e3d6000fd5b50505050611f14612afb565b6000611f1e611b93565b604051633ff37e8f60e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b600482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260248201529091506001600160a01b03821690633ff37e8f906044016020604051808303816000875af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190612f08565b50604051633ff37e8f60e01b815273d533a949740bb3306d119cc777fa900ba034cd52600482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260248201526001600160a01b03821690633ff37e8f906044016020604051808303816000875af115801561202e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120529190612f08565b50600061205f6001612788565b905060005b81811015612113576001600160a01b038316633ff37e8f612086600184612c58565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260248201526044016020604051808303816000875af11580156120e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210a9190612f08565b50600101612064565b50600354604051633ff37e8f60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260048201526001600160a01b03918216602482015290831690633ff37e8f906044016020604051808303816000875af115801561217a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219e9190612f08565b5060006121ab8447612f8e565b90507f80f97f878e16410266694f134ddf012f2be424f54f8b5cafa107eccc51d00d58816040516121de91815260200190565b60405180910390a1949350505050565b6000806121f9612455565b9050801561228357600954604051636197390160e11b815260048101839052600060248201526001600160a01b039091169063c32e7202906044016020604051808303816000875af1158015612253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122779190612ee6565b61228357600091505090565b600061228d6123e7565b9050801561231a57600b54600d546001600160a01b0390911690631a4d01d29083906122b882612c64565b6040516001600160e01b031960e086901b1681526004810193909352600f9190910b60248301526044820152606401600060405180830381600087803b15801561230157600080fd5b505af1158015612315573d6000803e3d6000fd5b505050505b478061232a576000935050505090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168260405160006040518083038185875af1925050503d8060008114612397576040519150601f19603f3d011682016040523d82523d6000602084013e61239c565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b8152509061157a5760405162461bcd60e51b81526004016107129190612e18565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015612431573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061062b9190612f08565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401612414565b60006119d3600b60009054906101000a90046001600160a01b03166001600160a01b031663bb7b8b806040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125029190612f08565b83906126e3565b6060600061251683612788565b905060008167ffffffffffffffff81111561253357612533613028565b60405190808252806020026020018201604052801561255c578160200160208202803683370190505b50905060005b828110156125a6576125748582612c58565b82828151811061258657612586612fda565b6001600160a01b0390921660209283029190910190910152600101612562565b509392505050565b600047806125be57600091505090565b6125c6612dce565b8181600d54600281106125db576125db612fda565b6020020152600b546001600160a01b0316630b4c7e4d83836125fc82612c88565b6040518463ffffffff1660e01b8152600401612619929190612ff0565b6000604051808303818588803b15801561263257600080fd5b505af1158015612646573d6000803e3d6000fd5b5050600c5460405163303acfe760e11b815260048101919091526001602482015273f403c135812408bfbe8713b5a23a04b3d48aae3193506360759fce925060440190506020604051808303816000875af11580156126a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cd9190612ee6565b6126da5760009250505090565b60019250505090565b6000670de0b6b3a76400006126f88385612f37565b611b779190612f6c565b600061270c611b93565b600354604051632550332960e11b81526001600160a01b038681166004830152918216602482015260448101859052911690634aa0665290606401602060405180830381865afa158015612764573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b779190612f08565b60006119d3825490565b60006127e7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b659092919063ffffffff16565b805190915015611b6057808060200190518101906128059190612ee6565b611b605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610712565b6060824710156128c55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610712565b6001600160a01b0385163b61291c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610712565b600080866001600160a01b03168587604051612938919061303e565b60006040518083038185875af1925050503d8060008114612975576040519150601f19603f3d011682016040523d82523d6000602084013e61297a565b606091505b509150915061298a828286612ca3565b979650505050505050565b60008181526001830160205260408120546129dc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556119d3565b5060006119d3565b60006119d3600854670de0b6b3a76400006129ff9190612fa5565b61139684612cdc565b60008181526001830160205260408120548015612af1576000612a2c600183612f8e565b8554909150600090612a4090600190612f8e565b9050818114612aa5576000866000018281548110612a6057612a60612fda565b9060005260206000200154905080876000018481548110612a8357612a83612fda565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ab657612ab661305a565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506119d3565b60009150506119d3565b6004546001600160a01b031680612b0f5750565b6006548015612bba576040516370a0823160e01b8152306004820152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b9060009082906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190612f08565b90508015612bb757612bb784612ba683866126e3565b6001600160a01b0385169190612d5f565b50505b6005548015611b60576040516370a0823160e01b815230600482015273d533a949740bb3306d119cc777fa900ba034cd529060009082906370a0823190602401602060405180830381865afa158015612c17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3b9190612f08565b90508015612c5157612c5185612ba683866126e3565b5050505050565b6000611b778383612d8f565b60006119d3600854670de0b6b3a7640000612c7f9190612f8e565b61139684612486565b60006119d3600754670de0b6b3a76400006129ff9190612f8e565b60608315612cb2575081611b77565b825115612cc25782518084602001fd5b8160405162461bcd60e51b81526004016107129190612e18565b60006119d3600b60009054906101000a90046001600160a01b03166001600160a01b031663bb7b8b806040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d589190612f08565b8390612db9565b6040516001600160a01b038316602482015260448101829052611b6090849063a9059cbb60e01b90606401611b29565b6000826000018281548110612da657612da6612fda565b9060005260206000200154905092915050565b6000816126f8670de0b6b3a764000085612f37565b60405180604001604052806002906020820280368337509192915050565b60005b83811015612e07578181015183820152602001612def565b83811115611c885750506000910152565b6020815260008251806020840152612e37816040850160208701612dec565b601f01601f19169190910160400192915050565b6001600160a01b0381168114612e6057600080fd5b50565b600060208284031215612e7557600080fd5b8135611b7781612e4b565b600060208284031215612e9257600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015612eda5783516001600160a01b031683529284019291840191600101612eb5565b50909695505050505050565b600060208284031215612ef857600080fd5b81518015158114611b7757600080fd5b600060208284031215612f1a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612f5157612f51612f21565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612f8957634e487b7160e01b600052601260045260246000fd5b500490565b600082821015612fa057612fa0612f21565b500390565b60008219821115612fb857612fb8612f21565b500190565b600060208284031215612fcf57600080fd5b8151611b7781612e4b565b634e487b7160e01b600052603260045260246000fd5b60608101818460005b6002811015613018578151835260209283019290910190600101612ff9565b5050508260408301529392505050565b634e487b7160e01b600052604160045260246000fd5b60008251613050818460208701612dec565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe756e617574686f72697a65642061636365737300000000000000000000000000a2646970667358221220edb1f145197cf15b7091420f3d77d9c5e33ba3c6c5339bb44340e7c8fc29364c64736f6c634300080a00330000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d0000000000000000000000006175ce0d8b90097c5aea1a15d6aba972581188860000000000000000000000000000000000000000000000000000000000000019000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f670220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d7
Deployed Bytecode
0x6080604052600436106101fc5760003560e01c80637bdcdaff1161010d578063c2bddf31116100a0578063e9eb50881161006f578063e9eb50881461058c578063ecf8db0a146105ac578063fbfa77cf146105cc578063fc0e74d114610600578063ff0af85b1461061557600080fd5b8063c2bddf311461052f578063c7b9d5301461054f578063d0e30db01461056f578063dbbd47d41461057757600080fd5b80639ec5a894116100dc5780639ec5a894146104b7578063b69ef8a8146104d7578063bf86d690146104ec578063c2b18aa01461050d57600080fd5b80637bdcdaff14610460578063853828b61461047657806386993bef1461048b5780639b61a924146104a157600080fd5b80633778851e1161019057806356be5f711161015f57806356be5f71146103d657806361240eea146103ec578063621e8fe1146104005780636f307dc31461042057806370aa17261461044057600080fd5b80633778851e1461035f5780633d509c971461037f5780634641257d1461039f57806349cabcdf146103b457600080fd5b80631fe4a686116101cc5780631fe4a686146102e1578063218751b2146102ff5780632e1a7d4d1461031f578063313c06a01461033f57600080fd5b8062435da51461020857806306fdde03146102545780631a55820d1461028d5780631c03e6cc146102b157600080fd5b3661020357005b600080fd5b34801561021457600080fd5b507f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e235b6040516001600160a01b0390911681526020015b60405180910390f35b34801561026057600080fd5b50604080518082018252600a81526909acae4de8ae8d086ecf60b31b6020820152905161024b9190612e18565b34801561029957600080fd5b506102a360085481565b60405190815260200161024b565b3480156102bd57600080fd5b506102d16102cc366004612e63565b610630565b604051901515815260200161024b565b3480156102ed57600080fd5b506000546001600160a01b0316610237565b34801561030b57600080fd5b50600b54610237906001600160a01b031681565b34801561032b57600080fd5b506102d161033a366004612e80565b61087a565b34801561034b57600080fd5b50600a54610237906001600160a01b031681565b34801561036b57600080fd5b506102a361037a366004612e80565b61093b565b34801561038b57600080fd5b506102d161039a366004612e63565b610a30565b3480156103ab57600080fd5b506102a3610b63565b3480156103c057600080fd5b506103d46103cf366004612e80565b610bda565b005b3480156103e257600080fd5b506102a360075481565b3480156103f857600080fd5b5060006102d1565b34801561040c57600080fd5b50600454610237906001600160a01b031681565b34801561042c57600080fd5b50600354610237906001600160a01b031681565b34801561044c57600080fd5b506103d461045b366004612e80565b610cf7565b34801561046c57600080fd5b506102a3600d5481565b34801561048257600080fd5b506102a3610eb4565b34801561049757600080fd5b506102a3600c5481565b3480156104ad57600080fd5b506102a360065481565b3480156104c357600080fd5b50600954610237906001600160a01b031681565b3480156104e357600080fd5b506102a3610f74565b3480156104f857600080fd5b506003546102d190600160a01b900460ff1681565b34801561051957600080fd5b50610522610fa2565b60405161024b9190612e99565b34801561053b57600080fd5b506103d461054a366004612e63565b610fae565b34801561055b57600080fd5b506103d461056a366004612e63565b611139565b6102d16111d6565b34801561058357600080fd5b506102a36112db565b34801561059857600080fd5b506103d46105a7366004612e80565b611584565b3480156105b857600080fd5b506103d46105c7366004612e80565b61169a565b3480156105d857600080fd5b506102377f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d81565b34801561060c57600080fd5b506103d4611857565b34801561062157600080fd5b506102a360055481565b905090565b60007f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156106ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d09190612ee6565b6040518060400160405280601381526020016000805160206130718339815191528152509061071b5760405162461bcd60e51b81526004016107129190612e18565b60405180910390fd5b506001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b1480159061075757506003546001600160a01b03838116911614155b801561078057506001600160a01b03821673d533a949740bb3306d119cc777fa900ba034cd5214155b60405180604001604052806014815260200173125b9d985b1a59081d1bdad95b881d1bc818591960621b815250906107cb5760405162461bcd60e51b81526004016107129190612e18565b506001600160a01b038216600090815260026020526040902054156107f257506000919050565b6107fd600183611b7e565b506000610808611b93565b905061081f6001600160a01b038416826000611a18565b6108356001600160a01b03841682600019611a18565b6040516001600160a01b03841681527f851bbb4304bf0768ed98b97e429b5bd1dcc1f194b36cd1650f40293e951ae3939060200160405180910390a150600192915050565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d16146108e85760405162461bcd60e51b81526004016107129190612e18565b50816108f657506000919050565b6108ff82611bc7565b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a1506001919050565b600080734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b49190612f08565b905060006109cc8269152d02c7e14af6800000611e7c565b90506103e881106109e1575060009392505050565b6103e8818103906000906109f58388612f37565b6109ff9190612f6c565b90506000610a18856a52b7d2dcc80cd2e4000000612f8e565b905080821115610a26578091505b5095945050505050565b60007f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190612ee6565b60405180604001604052806013815260200160008051602061307183398151915281525090610b125760405162461bcd60e51b81526004016107129190612e18565b50610b1e600183611e95565b610b2a57506000919050565b6040516001600160a01b03831681527f36bd04094fa067bb9471a8fbdb0a6e8a43424a2566ad3a740c88973fa40a31189060200161092b565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d1614610bd15760405162461bcd60e51b81526004016107129190612e18565b5061062b611eaa565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c789190612ee6565b60405180604001604052806013815260200160008051602061307183398151915281525090610cba5760405162461bcd60e51b81526004016107129190612e18565b5060078190556040518181527f4ede3e4e9f7997fda6ff4a12d6c43d5c9e1e2055065cbc15f902f504f72dc8c0906020015b60405180910390a150565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d959190612ee6565b60405180604001604052806013815260200160008051602061307183398151915281525090610dd75760405162461bcd60e51b81526004016107129190612e18565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a7640000821115610e265760405162461bcd60e51b81526004016107129190612e18565b506004546001600160a01b0316610e7f5760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d757374206265207365740000006044820152606401610712565b60058190556040518181527f1a8542dffa4956932e66916113e6a123e123956172fbc0e2e59df92b8a87d8e690602001610cec565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d1614610f225760405162461bcd60e51b81526004016107129190612e18565b506000610f2d6121ee565b905080610f3c57600091505090565b6040518181527f3d5a341dc6a12221fcf31279cef3771f8fad757b2d9261f97605ccc17c2574249060200160405180910390a1919050565b6000610f98610f816123e7565b610f89612455565b610f939190612fa5565b612486565b61062b9047612fa5565b606061062b6001612509565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611028573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104c9190612ee6565b6040518060400160405280601381526020016000805160206130718339815191528152509061108e5760405162461bcd60e51b81526004016107129190612e18565b5060408051808201909152601881527f7a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060208201526001600160a01b0382166110ea5760405162461bcd60e51b81526004016107129190612e18565b50600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f17d7ba6682f162782054b119192f8e5b98fe7090b4bec7a55fc7075d9cd859ee90602001610cec565b60005460408051808201909152601381526000805160206130718339815191526020820152906001600160a01b031633146111875760405162461bcd60e51b81526004016107129190612e18565b50600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f46d58e3fa07bf19b1d27240f0e286b27e9f7c1b0d88933333fe833b60eec541290602001610cec565b60408051808201909152601381526000805160206130718339815191526020820152600090336001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d16146112445760405162461bcd60e51b81526004016107129190612e18565b5060035460408051808201909152601481527329ba3930ba32b3bc9034b99039b43aba3237bbb760611b602082015290600160a01b900460ff161561129c5760405162461bcd60e51b81526004016107129190612e18565b506112a56125ae565b6112af5750600090565b6040517fed21248cb703b524cc0029bb8669df941baca560163a3bc6ad184e7e9c26807090600090a190565b6009546040516246613160e11b81523060048201526000916001600160a01b03169082908290628cc26290602401602060405180830381865afa158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190612f08565b90508061135a5760009250505090565b60006113a1734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b61139c600654670de0b6b3a764000061138d9190612f8e565b6113968661093b565b906126e3565b612702565b6113d973d533a949740bb3306d119cc777fa900ba034cd5261139c600554670de0b6b3a76400006113d29190612f8e565b86906126e3565b6113e39190612fa5565b905060006113f16001612788565b905060005b8181101561157a57604051632061aa2360e11b8152600481018290526000906001600160a01b038716906340c3544690602401602060405180830381865afa158015611446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146a9190612fbd565b90506000816001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d09190612fbd565b6001600160a01b0381166000908152600260205260409020549091506114f7575050611572565b6040516246613160e11b81523060048201526115639082906001600160a01b03851690628cc26290602401602060405180830381865afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190612f08565b61156d9086612fa5565b945050505b6001016113f6565b5090949350505050565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116229190612ee6565b604051806040016040528060138152602001600080516020613071833981519152815250906116645760405162461bcd60e51b81526004016107129190612e18565b5060088190556040518181527fb2861fed34a4613f8f25f46553a23408a3364ee9ddc4ef6714f0a81d856e41a790602001610cec565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611714573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117389190612ee6565b6040518060400160405280601381526020016000805160206130718339815191528152509061177a5760405162461bcd60e51b81526004016107129190612e18565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a76400008211156117c95760405162461bcd60e51b81526004016107129190612e18565b506004546001600160a01b03166118225760405162461bcd60e51b815260206004820152601d60248201527f436f6d6d756e6974792072657365727665206d757374206265207365740000006044820152606401610712565b60068190556040518181527f2c3c7d70a1dfbfaf74447753b8a73e1323aa10b32b9209742db563671e14b13c90602001610cec565b60408051808201909152601381526000805160206130718339815191526020820152336001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d16146118c25760405162461bcd60e51b81526004016107129190612e18565b5060035460408051808201909152601481527329ba3930ba32b3bc9034b99039b43aba3237bbb760611b602082015290600160a01b900460ff161561191a5760405162461bcd60e51b81526004016107129190612e18565b506003805460ff60a01b1916600160a01b1790556040517f4426aa1fb73e391071491fcfe21a88b5c38a0a0333a1f6e77161470439704cf890600090a1565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa1580156119af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d39190612fbd565b92915050565b6040516321f8a72160e01b81526c39bbb0b83832b92937baba32b960991b60048201526000906001600160a01b038316906321f8a72190602401611992565b801580611a925750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190612f08565b155b611afd5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610712565b6040516001600160a01b038316602482015260448101829052611b6090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612792565b505050565b6060611b748484600085612864565b90505b9392505050565b6000611b77836001600160a01b038416612995565b600061062b7f000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d76001600160a01b03166119d9565b600047828110611c8e576040516001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d16908490600081818185875af1925050503d8060008114611c3a576040519150601f19603f3d011682016040523d82523d6000602084013e611c3f565b606091505b505060408051808201909152600f81526e1d1c985b9cd9995c8819985a5b1959608a1b602082015290925082611c885760405162461bcd60e51b81526004016107129190612e18565b50505050565b8083036000611c9c826129e4565b90506000611ca86123e7565b611cb29083612f8e565b600954604051636197390160e11b815260048101839052600060248201529192506001600160a01b03169063c32e7202906044016020604051808303816000875af1158015611d05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d299190612ee6565b611d3557505050505050565b611d3d612dce565b8381600d5460028110611d5257611d52612fda565b6020020152600b5460405163e310327360e01b81526001600160a01b039091169063e310327390611d899084908790600401612ff0565b600060405180830381600087803b158015611da357600080fd5b505af1158015611db7573d6000803e3d6000fd5b50506040516001600160a01b037f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d169250899150600081818185875af1925050503d8060008114611e24576040519150601f19603f3d011682016040523d82523d6000602084013e611e29565b606091505b505060408051808201909152600f81526e1d1c985b9cd9995c8819985a5b1959608a1b602082015290965086611e725760405162461bcd60e51b81526004016107129190612e18565b5050505050505050565b6000818381611e8d57611e8d612f56565b049392505050565b6000611b77836001600160a01b038416612a08565b60095460408051631e8c5c8960e11b8152905160009247926001600160a01b0390911691633d18b91291600480820192879290919082900301818387803b158015611ef457600080fd5b505af1158015611f08573d6000803e3d6000fd5b50505050611f14612afb565b6000611f1e611b93565b604051633ff37e8f60e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b600482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260248201529091506001600160a01b03821690633ff37e8f906044016020604051808303816000875af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190612f08565b50604051633ff37e8f60e01b815273d533a949740bb3306d119cc777fa900ba034cd52600482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260248201526001600160a01b03821690633ff37e8f906044016020604051808303816000875af115801561202e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120529190612f08565b50600061205f6001612788565b905060005b81811015612113576001600160a01b038316633ff37e8f612086600184612c58565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260248201526044016020604051808303816000875af11580156120e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210a9190612f08565b50600101612064565b50600354604051633ff37e8f60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260048201526001600160a01b03918216602482015290831690633ff37e8f906044016020604051808303816000875af115801561217a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219e9190612f08565b5060006121ab8447612f8e565b90507f80f97f878e16410266694f134ddf012f2be424f54f8b5cafa107eccc51d00d58816040516121de91815260200190565b60405180910390a1949350505050565b6000806121f9612455565b9050801561228357600954604051636197390160e11b815260048101839052600060248201526001600160a01b039091169063c32e7202906044016020604051808303816000875af1158015612253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122779190612ee6565b61228357600091505090565b600061228d6123e7565b9050801561231a57600b54600d546001600160a01b0390911690631a4d01d29083906122b882612c64565b6040516001600160e01b031960e086901b1681526004810193909352600f9190910b60248301526044820152606401600060405180830381600087803b15801561230157600080fd5b505af1158015612315573d6000803e3d6000fd5b505050505b478061232a576000935050505090565b60007f0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d6001600160a01b03168260405160006040518083038185875af1925050503d8060008114612397576040519150601f19603f3d011682016040523d82523d6000602084013e61239c565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b8152509061157a5760405162461bcd60e51b81526004016107129190612e18565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015612431573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061062b9190612f08565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401612414565b60006119d3600b60009054906101000a90046001600160a01b03166001600160a01b031663bb7b8b806040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125029190612f08565b83906126e3565b6060600061251683612788565b905060008167ffffffffffffffff81111561253357612533613028565b60405190808252806020026020018201604052801561255c578160200160208202803683370190505b50905060005b828110156125a6576125748582612c58565b82828151811061258657612586612fda565b6001600160a01b0390921660209283029190910190910152600101612562565b509392505050565b600047806125be57600091505090565b6125c6612dce565b8181600d54600281106125db576125db612fda565b6020020152600b546001600160a01b0316630b4c7e4d83836125fc82612c88565b6040518463ffffffff1660e01b8152600401612619929190612ff0565b6000604051808303818588803b15801561263257600080fd5b505af1158015612646573d6000803e3d6000fd5b5050600c5460405163303acfe760e11b815260048101919091526001602482015273f403c135812408bfbe8713b5a23a04b3d48aae3193506360759fce925060440190506020604051808303816000875af11580156126a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cd9190612ee6565b6126da5760009250505090565b60019250505090565b6000670de0b6b3a76400006126f88385612f37565b611b779190612f6c565b600061270c611b93565b600354604051632550332960e11b81526001600160a01b038681166004830152918216602482015260448101859052911690634aa0665290606401602060405180830381865afa158015612764573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b779190612f08565b60006119d3825490565b60006127e7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b659092919063ffffffff16565b805190915015611b6057808060200190518101906128059190612ee6565b611b605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610712565b6060824710156128c55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610712565b6001600160a01b0385163b61291c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610712565b600080866001600160a01b03168587604051612938919061303e565b60006040518083038185875af1925050503d8060008114612975576040519150601f19603f3d011682016040523d82523d6000602084013e61297a565b606091505b509150915061298a828286612ca3565b979650505050505050565b60008181526001830160205260408120546129dc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556119d3565b5060006119d3565b60006119d3600854670de0b6b3a76400006129ff9190612fa5565b61139684612cdc565b60008181526001830160205260408120548015612af1576000612a2c600183612f8e565b8554909150600090612a4090600190612f8e565b9050818114612aa5576000866000018281548110612a6057612a60612fda565b9060005260206000200154905080876000018481548110612a8357612a83612fda565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ab657612ab661305a565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506119d3565b60009150506119d3565b6004546001600160a01b031680612b0f5750565b6006548015612bba576040516370a0823160e01b8152306004820152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b9060009082906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190612f08565b90508015612bb757612bb784612ba683866126e3565b6001600160a01b0385169190612d5f565b50505b6005548015611b60576040516370a0823160e01b815230600482015273d533a949740bb3306d119cc777fa900ba034cd529060009082906370a0823190602401602060405180830381865afa158015612c17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3b9190612f08565b90508015612c5157612c5185612ba683866126e3565b5050505050565b6000611b778383612d8f565b60006119d3600854670de0b6b3a7640000612c7f9190612f8e565b61139684612486565b60006119d3600754670de0b6b3a76400006129ff9190612f8e565b60608315612cb2575081611b77565b825115612cc25782518084602001fd5b8160405162461bcd60e51b81526004016107129190612e18565b60006119d3600b60009054906101000a90046001600160a01b03166001600160a01b031663bb7b8b806040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d589190612f08565b8390612db9565b6040516001600160a01b038316602482015260448101829052611b6090849063a9059cbb60e01b90606401611b29565b6000826000018281548110612da657612da6612fda565b9060005260206000200154905092915050565b6000816126f8670de0b6b3a764000085612f37565b60405180604001604052806002906020820280368337509192915050565b60005b83811015612e07578181015183820152602001612def565b83811115611c885750506000910152565b6020815260008251806020840152612e37816040850160208701612dec565b601f01601f19169190910160400192915050565b6001600160a01b0381168114612e6057600080fd5b50565b600060208284031215612e7557600080fd5b8135611b7781612e4b565b600060208284031215612e9257600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015612eda5783516001600160a01b031683529284019291840191600101612eb5565b50909695505050505050565b600060208284031215612ef857600080fd5b81518015158114611b7757600080fd5b600060208284031215612f1a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612f5157612f51612f21565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612f8957634e487b7160e01b600052601260045260246000fd5b500490565b600082821015612fa057612fa0612f21565b500390565b60008219821115612fb857612fb8612f21565b500190565b600060208284031215612fcf57600080fd5b8151611b7781612e4b565b634e487b7160e01b600052603260045260246000fd5b60608101818460005b6002811015613018578151835260209283019290910190600101612ff9565b5050508260408301529392505050565b634e487b7160e01b600052604160045260246000fd5b60008251613050818460208701612dec565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe756e617574686f72697a65642061636365737300000000000000000000000000a2646970667358221220edb1f145197cf15b7091420f3d77d9c5e33ba3c6c5339bb44340e7c8fc29364c64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d0000000000000000000000006175ce0d8b90097c5aea1a15d6aba972581188860000000000000000000000000000000000000000000000000000000000000019000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f670220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d7
-----Decoded View---------------
Arg [0] : vault_ (address): 0x2F1682c6782C58d2E95E4165328180F9d65A6B6D
Arg [1] : strategist_ (address): 0x6175Ce0D8B90097c5AEa1A15d6aBa97258118886
Arg [2] : convexPid_ (uint256): 25
Arg [3] : curvePool_ (address): 0xDC24316b9AE028F1497c275EB9192a3Ea0f67022
Arg [4] : curveIndex_ (uint256): 0
Arg [5] : addressProvider_ (address): 0xa298d39715AE492e4CAF3Ccb33cBF57abC5238d7
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000002f1682c6782c58d2e95e4165328180f9d65a6b6d
Arg [1] : 0000000000000000000000006175ce0d8b90097c5aea1a15d6aba97258118886
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000019
Arg [3] : 000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f67022
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d7
Deployed Bytecode Sourcemap
108464:6751:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42386:108;;;;;;;;;;-1:-1:-1;42909:13:0;42386:108;;;-1:-1:-1;;;;;199:32:1;;;181:51;;169:2;154:18;42386:108:0;;;;;;;;109535:101;;;;;;;;;;-1:-1:-1;109609:19:0;;;;;;;;;;;-1:-1:-1;;;109609:19:0;;;;109535:101;;;;109609:19;109535:101;:::i;92516:36::-;;;;;;;;;;;;;;;;;;;1040:25:1;;;1028:2;1013:18;92516:36:0;894:177:1;101115:608:0;;;;;;;;;;-1:-1:-1;101115:608:0;;;;;:::i;:::-;;:::i;:::-;;;1629:14:1;;1622:22;1604:41;;1592:2;1577:18;101115:608:0;1464:187:1;103534:100:0;;;;;;;;;;-1:-1:-1;103588:7:0;103615:11;-1:-1:-1;;;;;103615:11:0;103534:100;;92759:30;;;;;;;;;;-1:-1:-1;92759:30:0;;;;-1:-1:-1;;;;;92759:30:0;;;96289:211;;;;;;;;;;-1:-1:-1;96289:211:0;;;;;:::i;:::-;;:::i;92713:16::-;;;;;;;;;;-1:-1:-1;92713:16:0;;;;-1:-1:-1;;;;;92713:16:0;;;29369:867;;;;;;;;;;-1:-1:-1;29369:867:0;;;;;:::i;:::-;;:::i;101907:220::-;;;;;;;;;;-1:-1:-1;101907:220:0;;;;;:::i;:::-;;:::i;97283:101::-;;;;;;;;;;;;;:::i;99676:254::-;;;;;;;;;;-1:-1:-1;99676:254:0;;;;;:::i;:::-;;:::i;:::-;;92405:35;;;;;;;;;;;;;;;;104397:96;;;;;;;;;;-1:-1:-1;104456:4:0;104397:96;;92083:31;;;;;;;;;;-1:-1:-1;92083:31:0;;;;-1:-1:-1;;;;;92083:31:0;;;91949:24;;;;;;;;;;-1:-1:-1;91949:24:0;;;;-1:-1:-1;;;;;91949:24:0;;;98380:446;;;;;;;;;;-1:-1:-1;98380:446:0;;;;;:::i;:::-;;:::i;92885:25::-;;;;;;;;;;;;;;;;96751:310;;;;;;;;;;;;;:::i;92810:24::-;;;;;;;;;;;;;;;;92317:39;;;;;;;;;;;;;;;;92629:29;;;;;;;;;;-1:-1:-1;92629:29:0;;;;-1:-1:-1;;;;;92629:29:0;;;109644:155;;;;;;;;;;;;;:::i;92003:22::-;;;;;;;;;;-1:-1:-1;92003:22:0;;;;-1:-1:-1;;;92003:22:0;;;;;;103806:123;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;97914:281::-;;;;;;;;;;-1:-1:-1;97914:281:0;;;;;:::i;:::-;;:::i;100578:220::-;;;;;;;;;;-1:-1:-1;100578:220:0;;;;;:::i;:::-;;:::i;95777:199::-;;;:::i;102357:1045::-;;;;;;;;;;;;;:::i;100154:260::-;;;;;;;;;;-1:-1:-1;100154:260:0;;;;;:::i;:::-;;:::i;99011:446::-;;;;;;;;;;-1:-1:-1;99011:446:0;;;;;:::i;:::-;;:::i;92178:30::-;;;;;;;;;;;;;;;97471:166;;;;;;;;;;;;;:::i;92229:39::-;;;;;;;;;;;;;;;;42472:14;42465:21;;42386:108;:::o;101115:608::-;101197:4;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;;101236:23:0;::::1;91179:42;101236:23;::::0;::::1;::::0;:56:::1;;-1:-1:-1::0;101281:10:0::1;::::0;-1:-1:-1;;;;;101263:29:0;;::::1;101281:10:::0;::::1;101263:29;;101236:56;:83;;;;-1:-1:-1::0;;;;;;101296:23:0;::::1;91083:42;101296:23;;101236:83;101334:26;;;;;;;;;;;;;-1:-1:-1::0;;;101334:26:0::1;;::::0;101214:157:::1;;;;;-1:-1:-1::0;;;101214:157:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;11548:23:0;;11494:4;6950:19;;;:12;:19;;;;;;:24;101382:48:::1;;-1:-1:-1::0;101425:5:0::1;101115:608:::0;;;:::o;101382:48::-:1;101441:25;:13;101459:6:::0;101441:17:::1;:25::i;:::-;;101477:22;101510:16;:14;:16::i;:::-;101477:50:::0;-1:-1:-1;101538:45:0::1;-1:-1:-1::0;;;;;101538:26:0;::::1;101477:50:::0;101581:1:::1;101538:26;:45::i;:::-;101594:61;-1:-1:-1::0;;;;;101594:26:0;::::1;101621:14:::0;-1:-1:-1;;101594:26:0::1;:61::i;:::-;101671:22;::::0;-1:-1:-1;;;;;199:32:1;;181:51;;101671:22:0::1;::::0;169:2:1;154:18;101671:22:0::1;;;;;;;-1:-1:-1::0;101711:4:0::1;::::0;101115:608;-1:-1:-1;;101115:608:0:o;96289:211::-;94250:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;94250:25:0;;;;96361:4;;94229:10;-1:-1:-1;;;;;94243:5:0;94229:19;;94221:55;;;;-1:-1:-1;;;94221:55:0;;;;;;;;:::i;:::-;-1:-1:-1;96382:12:0;96378:30:::1;;-1:-1:-1::0;96403:5:0::1;101115:608:::0;;;:::o;96378:30::-:1;96419:18;96429:7;96419:9;:18::i;:::-;96453:17;::::0;1040:25:1;;;96453:17:0::1;::::0;1028:2:1;1013:18;96453:17:0::1;;;;;;;;-1:-1:-1::0;96488:4:0::1;96289:211:::0;;;:::o;29369:867::-;29435:7;29489:22;29303:42;-1:-1:-1;;;;;29514:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29489:49;-1:-1:-1;29580:20:0;29603:40;29489:49;29044:10;29603:27;:40::i;:::-;29580:63;;29134:4;29705:12;:28;29701:42;;-1:-1:-1;29742:1:0;;29369:867;-1:-1:-1;;;29369:867:0:o;29701:42::-;29134:4;28699:5;;;;29788:17;;29971:21;28699:5;29971:9;:21;:::i;:::-;29970:38;;;;:::i;:::-;29950:58;-1:-1:-1;30082:21:0;30106:28;30120:14;29200;30106:28;:::i;:::-;30082:52;;30161:13;30149:9;:25;30145:56;;;30188:13;30176:25;;30145:56;-1:-1:-1;30219:9:0;29369:867;-1:-1:-1;;;;;29369:867:0:o;101907:220::-;101992:4;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;-1:-1:-1;102014:28:0::1;:13;102035:6:::0;102014:20:::1;:28::i;:::-;102009:47;;-1:-1:-1::0;102051:5:0::1;101115:608:::0;;;:::o;102009:47::-:1;102072:25;::::0;-1:-1:-1;;;;;199:32:1;;181:51;;102072:25:0::1;::::0;169:2:1;154:18;102072:25:0::1;14:224:1::0;97283:101:0;94250:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;94250:25:0;;;;97339:7;;94229:10;-1:-1:-1;;;;;94243:5:0;94229:19;;94221:55;;;;-1:-1:-1;;;94221:55:0;;;;;;;;:::i;:::-;;97366:10:::1;:8;:10::i;99676:254::-:0;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;-1:-1:-1;99816:20:0::1;:44:::0;;;99876:46:::1;::::0;1040:25:1;;;99876:46:0::1;::::0;1028:2:1;1013:18;99876:46:0::1;;;;;;;;99676:254:::0;:::o;98380:446::-;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;-1:-1:-1;98581:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;98581:20:0::1;::::0;::::1;::::0;43500:4:::1;98536:43:::0;::::1;;98528:74;;;;-1:-1:-1::0;;;98528:74:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;98621:16:0::1;::::0;-1:-1:-1;;;;;98621:16:0::1;98613:72;;;::::0;-1:-1:-1;;;98613:72:0;;5135:2:1;98613:72:0::1;::::0;::::1;5117:21:1::0;5174:2;5154:18;;;5147:30;5213:31;5193:18;;;5186:59;5262:18;;98613:72:0::1;4933:353:1::0;98613:72:0::1;98696:24;:52:::0;;;98764:54:::1;::::0;1040:25:1;;;98764:54:0::1;::::0;1028:2:1;1013:18;98764:54:0::1;894:177:1::0;96751:310:0;96850:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;96850:25:0;;;;96801:7;;96829:10;-1:-1:-1;;;;;96843:5:0;96829:19;;96821:55;;;;-1:-1:-1;;;96821:55:0;;;;;;;;:::i;:::-;;96887:24;96914:14;:12;:14::i;:::-;96887:41;-1:-1:-1;96943:21:0;96939:35;;96973:1;96966:8;;;96751:310;:::o;96939:35::-;96990:29;;1040:25:1;;;96990:29:0;;1028:2:1;1013:18;96990:29:0;;;;;;;97037:16;96751:310;-1:-1:-1;96751:310:0:o;109644:155::-;109693:7;109743:48;109778:12;:10;:12::i;:::-;109759:16;:14;:16::i;:::-;:31;;;;:::i;:::-;109743:15;:48::i;:::-;109720:71;;112743:21;109720:71;:::i;103806:123::-;103862:16;103898:23;:13;:21;:23::i;97914:281::-;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;-1:-1:-1;98055:30:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;-1:-1:-1;;;;;98022:31:0;::::1;98014:72;;;;-1:-1:-1::0;;;98014:72:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;98097:16:0::1;:36:::0;;-1:-1:-1;;;;;;98097:36:0::1;-1:-1:-1::0;;;;;98097:36:0;::::1;::::0;;::::1;::::0;;;98149:38:::1;::::0;181:51:1;;;98149:38:0::1;::::0;169:2:1;154:18;98149:38:0::1;14:224:1::0;100578:220:0;100673:11;;100686:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;100686:25:0;;;;;-1:-1:-1;;;;;100673:11:0;100659:10;:25;100651:61;;;;-1:-1:-1;;;100651:61:0;;;;;;;;:::i;:::-;-1:-1:-1;100723:11:0;:25;;-1:-1:-1;;;;;;100723:25:0;-1:-1:-1;;;;;100723:25:0;;;;;;;;100764:26;;181:51:1;;;100764:26:0;;169:2:1;154:18;100764:26:0;14:224:1;95777:199:0;94250:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;94250:25:0;;;;95841:4;;94229:10;-1:-1:-1;;;;;94243:5:0;94229:19;;94221:55;;;;-1:-1:-1;;;94221:55:0;;;;;;;;:::i;:::-;-1:-1:-1;95867:10:0::1;::::0;95879:23:::1;::::0;;;;::::1;::::0;;;95867:10:::1;95879:23:::0;;-1:-1:-1;;;95879:23:0::1;::::0;::::1;::::0;;-1:-1:-1;;;95867:10:0;::::1;;;95866:11;95858:45;;;;-1:-1:-1::0;;;95858:45:0::1;;;;;;;;:::i;:::-;;95919:10;:8;:10::i;:::-;95914:29;;-1:-1:-1::0;95938:5:0::1;97283:101:::0;:::o;95914:29::-:1;95959:9;::::0;::::1;::::0;;;::::1;95777:199:::0;:::o;102357:1045::-;102458:7;;102497:30;;-1:-1:-1;;;102497:30:0;;102521:4;102497:30;;;181:51:1;102412:7:0;;-1:-1:-1;;;;;102458:7:0;;102412;;102458;;102497:15;;154:18:1;;102497:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102476:51;-1:-1:-1;102542:15:0;102538:29;;102566:1;102559:8;;;;102357:1045;:::o;102538:29::-;102578:20;102754:167;91179:42;102825:81;102881:24;;43500:4;102864:41;;;;:::i;:::-;102825:28;102842:10;102825:16;:28::i;:::-;:38;;:81::i;:::-;102754:20;:167::i;:::-;102601:137;91083:42;102664:63;102702:24;;43500:4;102685:41;;;;:::i;:::-;102664:10;;:20;:63::i;102601:137::-;:320;;;;:::i;:::-;102578:343;;102932:15;102950:22;:13;:20;:22::i;:::-;102932:40;;102988:9;102983:382;103003:7;102999:1;:11;102983:382;;;103095:24;;-1:-1:-1;;;103095:24:0;;;;;1040:25:1;;;103049:28:0;;-1:-1:-1;;;;;103095:21:0;;;;;1013:18:1;;103095:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103049:71;;103135:20;103158:13;-1:-1:-1;;;;;103158:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;11548:23:0;;11494:4;6950:19;;;:12;:19;;;;;;103135:50;;-1:-1:-1;103200:51:0;;103243:8;;;;103200:51;103317:35;;-1:-1:-1;;;103317:35:0;;103346:4;103317:35;;;181:51:1;103282:71:0;;103303:12;;-1:-1:-1;;;;;103317:20:0;;;;;154:18:1;;103317:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;103282:71::-;103266:87;;;;:::i;:::-;;;103034:331;;102983:382;28401:1;28397:5;102983:382;;;-1:-1:-1;103382:12:0;;102357:1045;-1:-1:-1;;;;102357:1045:0:o;100154:260::-;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;-1:-1:-1;100296:21:0::1;:46:::0;;;100358:48:::1;::::0;1040:25:1;;;100358:48:0::1;::::0;1028:2:1;1013:18;100358:48:0::1;894:177:1::0;99011:446:0;42909:13;41627:52;;-1:-1:-1;;;41627:52:0;;-1:-1:-1;;;41627:52:0;;;3568:25:1;41668:10:0;3609:18:1;;;3602:60;-1:-1:-1;;;;;41627:22:0;;;;;;;3541:18:1;;41627:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41681:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41681:25:0;;;41619:88;;;;;-1:-1:-1;;;41619:88:0;;;;;;;;:::i;:::-;-1:-1:-1;99212:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;99212:20:0::1;::::0;::::1;::::0;43500:4:::1;99167:43:::0;::::1;;99159:74;;;;-1:-1:-1::0;;;99159:74:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;99252:16:0::1;::::0;-1:-1:-1;;;;;99252:16:0::1;99244:72;;;::::0;-1:-1:-1;;;99244:72:0;;5135:2:1;99244:72:0::1;::::0;::::1;5117:21:1::0;5174:2;5154:18;;;5147:30;5213:31;5193:18;;;5186:59;5262:18;;99244:72:0::1;4933:353:1::0;99244:72:0::1;99327:24;:52:::0;;;99395:54:::1;::::0;1040:25:1;;;99395:54:0::1;::::0;1028:2:1;1013:18;99395:54:0::1;894:177:1::0;97471:166:0;94250:25;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;94250:25:0;;;;94229:10;-1:-1:-1;;;;;94243:5:0;94229:19;;94221:55;;;;-1:-1:-1;;;94221:55:0;;;;;;;;:::i;:::-;-1:-1:-1;97539:10:0::1;::::0;97551:23:::1;::::0;;;;::::1;::::0;;;97539:10:::1;97551:23:::0;;-1:-1:-1;;;97551:23:0::1;::::0;::::1;::::0;;-1:-1:-1;;;97539:10:0;::::1;;;97538:11;97530:45;;;;-1:-1:-1::0;;;97530:45:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;97586:10:0::1;:17:::0;;-1:-1:-1;;;;97586:17:0::1;-1:-1:-1::0;;;97586:17:0::1;::::0;;97619:10:::1;::::0;::::1;::::0;97586:17;;97619:10:::1;97471:166::o:0;69317:186::-;69436:58;;-1:-1:-1;;;69436:58:0;;-1:-1:-1;;;69436:58:0;;;1040:25:1;69391:12:0;;-1:-1:-1;;;;;69436:19:0;;;;;1013:18:1;;69436:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69416:79;69317:186;-1:-1:-1;;69317:186:0:o;70499:194::-;70624:60;;-1:-1:-1;;;70624:60:0;;-1:-1:-1;;;70624:60:0;;;1040:25:1;70575:14:0;;-1:-1:-1;;;;;70624:19:0;;;;;1013:18:1;;70624:60:0;894:177:1;25538:616:0;25902:10;;;25901:62;;-1:-1:-1;25918:39:0;;-1:-1:-1;;;25918:39:0;;25942:4;25918:39;;;6074:34:1;-1:-1:-1;;;;;6144:15:1;;;6124:18;;;6117:43;25918:15:0;;;;;6009:18:1;;25918:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;25901:62;25879:166;;;;-1:-1:-1;;;25879:166:0;;6373:2:1;25879:166:0;;;6355:21:1;6412:2;6392:18;;;6385:30;6451:34;6431:18;;;6424:62;-1:-1:-1;;;6502:18:1;;;6495:52;6564:19;;25879:166:0;6171:418:1;25879:166:0;26083:62;;-1:-1:-1;;;;;6786:32:1;;26083:62:0;;;6768:51:1;6835:18;;;6828:34;;;26056:90:0;;26076:5;;-1:-1:-1;;;26106:22:0;6741:18:1;;26083:62:0;;;;-1:-1:-1;;26083:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;26083:62:0;-1:-1:-1;;;;;;26083:62:0;;;;;;;;;;26056:19;:90::i;:::-;25538:616;;;:::o;19502:229::-;19639:12;19671:52;19693:6;19701:4;19707:1;19710:12;19671:21;:52::i;:::-;19664:59;;19502:229;;;;;;:::o;10842:152::-;10912:4;10936:50;10941:3;-1:-1:-1;;;;;10961:23:0;;10936:4;:50::i;107873:126::-;107922:14;107956:35;:16;-1:-1:-1;;;;;107956:33:0;;:35::i;110389:1257::-;110453:12;112743:21;110594:27;;;110590:251;;110716:38;;-1:-1:-1;;;;;110724:5:0;110716:19;;110743:6;;110716:38;;;;110743:6;110716:19;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;110786:21:0;;;;;;;;;;;;-1:-1:-1;;;110786:21:0;;;;110702:52;;-1:-1:-1;110702:52:0;110769:39;;;;-1:-1:-1;;;110769:39:0;;;;;;;;:::i;:::-;;110823:7;;110389:1257;:::o;110590:251::-;28699:5;;;110904:32;111010:38;28699:5;111010:12;:38::i;:::-;110988:60;;111059:24;111100:12;:10;:12::i;:::-;111086:26;;:11;:26;:::i;:::-;111128:7;;:50;;-1:-1:-1;;;111128:50:0;;;;;7251:25:1;;;111128:7:0;7292:18:1;;;7285:50;111059:53:0;;-1:-1:-1;;;;;;111128:7:0;;:25;;7224:18:1;;111128:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111123:64;;111180:7;;;;;110389:1257;:::o;111123:64::-;111248:25;;:::i;:::-;111355:24;111333:7;111341:10;;111333:19;;;;;;;:::i;:::-;;;;:46;111390:9;;:58;;-1:-1:-1;;;111390:58:0;;-1:-1:-1;;;;;111390:9:0;;;;:36;;:58;;111427:7;;111436:11;;111390:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;111533:38:0;;-1:-1:-1;;;;;111541:5:0;111533:19;;-1:-1:-1;111560:6:0;;-1:-1:-1;111533:38:0;;;;111560:6;111533:19;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;111599:21:0;;;;;;;;;;;;-1:-1:-1;;;111599:21:0;;;;111519:52;;-1:-1:-1;111519:52:0;111582:39;;;;-1:-1:-1;;;111582:39:0;;;;;;;;:::i;:::-;;111632:7;;;;;;110389:1257;:::o;28731:143::-;28798:7;28854:1;28850;:5;;;;;:::i;:::-;;;28731:143;-1:-1:-1;;;28731:143:0:o;11170:158::-;11243:4;11267:53;11275:3;-1:-1:-1;;;;;11295:23:0;;11267:7;:53::i;104689:1000::-;104839:7;;:19;;;-1:-1:-1;;;104839:19:0;;;;104727:7;;112743:21;;-1:-1:-1;;;;;104839:7:0;;;;:17;;:19;;;;;104727:7;;104839:19;;;;;;;;104727:7;104839;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104918:28;:26;:28::i;:::-;104989:29;105021:16;:14;:16::i;:::-;105048:53;;-1:-1:-1;;;105048:53:0;;91179:42;105048:53;;;6074:34:1;91276:42:0;6124:18:1;;;6117:43;104989:48:0;;-1:-1:-1;;;;;;105048:22:0;;;;;6009:18:1;;105048:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;105144:53:0;;-1:-1:-1;;;105144:53:0;;91083:42;105144:53;;;6074:34:1;91276:42:0;6124:18:1;;;6117:43;-1:-1:-1;;;;;105144:22:0;;;;;6009:18:1;;105144:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;105250:15;105268:22;:13;:20;:22::i;:::-;105250:40;;105306:9;105301:137;105321:7;105317:1;:11;105301:137;;;-1:-1:-1;;;;;105367:22:0;;;105390:19;:13;105407:1;105390:16;:19::i;:::-;105367:59;;-1:-1:-1;;;;;;105367:59:0;;;;;;;-1:-1:-1;;;;;6092:15:1;;;105367:59:0;;;6074:34:1;91276:42:0;6124:18:1;;;6117:43;6009:18;;105367:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;28401:1:0;28397:5;105301:137;;;-1:-1:-1;105534:10:0;;105487:59;;-1:-1:-1;;;105487:59:0;;91276:42;105487:59;;;6074:34:1;-1:-1:-1;;;;;105534:10:0;;;6124:18:1;;;6117:43;105487:22:0;;;;;;6009:18:1;;105487:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;105559:18:0;105580:38;105603:15;112743:21;105580:38;:::i;:::-;105559:59;;105634:19;105642:10;105634:19;;;;1040:25:1;;1028:2;1013:18;;894:177;105634:19:0;;;;;;;;105671:10;104689:1000;-1:-1:-1;;;;104689:1000:0:o;111654:992::-;111705:7;111780:21;111804:16;:14;:16::i;:::-;111780:40;-1:-1:-1;111835:17:0;;111831:112;;111874:7;;:47;;-1:-1:-1;;;111874:47:0;;;;;7251:25:1;;;111874:7:0;7292:18:1;;;7285:50;-1:-1:-1;;;;;111874:7:0;;;;:25;;7224:18:1;;111874:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111869:62;;111930:1;111923:8;;;111654:992;:::o;111869:62::-;111997:17;112017:12;:10;:12::i;:::-;111997:32;-1:-1:-1;112044:13:0;;112040:222;;112074:9;;112171:10;;-1:-1:-1;;;;;112074:9:0;;;;:35;;112128:9;;112202:33;112128:9;112202:22;:33::i;:::-;112074:176;;-1:-1:-1;;;;;;112074:176:0;;;;;;;;;;8248:25:1;;;;8320:2;8309:22;;;;8289:18;;;8282:50;8348:18;;;8341:34;8221:18;;112074:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112040:222;112743:21;;112378:36;;112413:1;112406:8;;;;;111654:992;:::o;112378:36::-;112486:12;112512:5;-1:-1:-1;;;;;112504:19:0;112531:17;112504:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112485:68;;;112572:7;112581:21;;;;;;;;;;;;;-1:-1:-1;;;112581:21:0;;;112564:39;;;;;-1:-1:-1;;;112564:39:0;;;;;;;;:::i;107071:107::-;107143:2;;:27;;-1:-1:-1;;;107143:27:0;;107164:4;107143:27;;;181:51:1;107116:7:0;;-1:-1:-1;;;;;107143:2:0;;:12;;154:18:1;;107143:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;107277:116::-;107353:7;;:32;;-1:-1:-1;;;107353:32:0;;107379:4;107353:32;;;181:51:1;107326:7:0;;-1:-1:-1;;;;;107353:7:0;;:17;;154:18:1;;107353:32:0;14:224:1;115060:152:0;115127:7;115154:50;115174:9;;;;;;;;;-1:-1:-1;;;;;115174:9:0;-1:-1:-1;;;;;115174:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115154:9;;:19;:50::i;82676:417::-;82787:16;82821:11;82835:18;:9;:16;:18::i;:::-;82821:32;;82864:23;82904:3;82890:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82890:18:0;;82864:44;;82924:9;82919:143;82939:3;82935:1;:7;82919:143;;;82973:15;:9;82986:1;82973:12;:15::i;:::-;82961:6;82968:1;82961:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;82961:27:0;;;:9;;;;;;;;;;;:27;83032:3;;82919:143;;;-1:-1:-1;83079:6:0;82676:417;-1:-1:-1;;;82676:417:0:o;109807:574::-;109854:4;112743:21;;109969:40;;110004:5;109997:12;;;109807:574;:::o;109969:40::-;110020:25;;:::i;:::-;110078:17;110056:7;110064:10;;110056:19;;;;;;;:::i;:::-;;;;:39;110106:9;;-1:-1:-1;;;;;110106:9:0;:23;110137:17;110170:7;110192:33;110137:17;110192:14;:33::i;:::-;110106:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;110321:9:0;;110301:36;;-1:-1:-1;;;110301:36:0;;;;;7251:25:1;;;;110332:4:0;7292:18:1;;;7285:50;90967:42:0;;-1:-1:-1;110301:19:0;;-1:-1:-1;7224:18:1;;;-1:-1:-1;110301:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;110296:55;;110346:5;110339:12;;;;109807:574;:::o;110296:55::-;110369:4;110362:11;;;;109807:574;:::o;43600:122::-;43664:7;43391:4;43692:5;43696:1;43692;:5;:::i;:::-;43691:23;;;;:::i;107401:188::-;107487:7;107514:16;:14;:16::i;:::-;107560:10;;107514:67;;-1:-1:-1;;;107514:67:0;;-1:-1:-1;;;;;8776:15:1;;;107514:67:0;;;8758:34:1;107560:10:0;;;8808:18:1;;;8801:43;8860:18;;;8853:34;;;107514:29:0;;;;;8693:18:1;;107514:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;11667:117::-;11730:7;11757:19;11765:3;7151:18;;7068:109;27461:753;27885:23;27911:106;27953:4;27911:106;;;;;;;;;;;;;;;;;27919:5;-1:-1:-1;;;;;27911:27:0;;;:106;;;;;:::i;:::-;28032:17;;27885:132;;-1:-1:-1;28032:21:0;28028:179;;28129:10;28118:30;;;;;;;;;;;;:::i;:::-;28110:85;;;;-1:-1:-1;;;28110:85:0;;9100:2:1;28110:85:0;;;9082:21:1;9139:2;9119:18;;;9112:30;9178:34;9158:18;;;9151:62;-1:-1:-1;;;9229:18:1;;;9222:40;9279:19;;28110:85:0;8898:406:1;20635:510:0;20805:12;20863:5;20838:21;:30;;20830:81;;;;-1:-1:-1;;;20830:81:0;;9511:2:1;20830:81:0;;;9493:21:1;9550:2;9530:18;;;9523:30;9589:34;9569:18;;;9562:62;-1:-1:-1;;;9640:18:1;;;9633:36;9686:19;;20830:81:0;9309:402:1;20830:81:0;-1:-1:-1;;;;;17052:19:0;;;20922:60;;;;-1:-1:-1;;;20922:60:0;;9918:2:1;20922:60:0;;;9900:21:1;9957:2;9937:18;;;9930:30;9996:31;9976:18;;;9969:59;10045:18;;20922:60:0;9716:353:1;20922:60:0;20996:12;21010:23;21037:6;-1:-1:-1;;;;;21037:11:0;21056:5;21063:4;21037:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20995:73;;;;21086:51;21103:7;21112:10;21124:12;21086:16;:51::i;:::-;21079:58;20635:510;-1:-1:-1;;;;;;;20635:510:0:o;4757:414::-;4820:4;6950:19;;;:12;;;:19;;;;;;4837:327;;-1:-1:-1;4880:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;5063:18;;5041:19;;;:12;;;:19;;;;;;:40;;;;5096:11;;4837:327;-1:-1:-1;5147:5:0;5140:12;;113511:191;113583:7;113610:84;113672:21;;43500:4;113655:38;;;;:::i;:::-;113610:34;113626:17;113610:15;:34::i;5347:1420::-;5413:4;5552:19;;;:12;;;:19;;;;;;5588:15;;5584:1176;;5963:21;5987:14;6000:1;5987:10;:14;:::i;:::-;6036:18;;5963:38;;-1:-1:-1;6016:17:0;;6036:22;;6057:1;;6036:22;:::i;:::-;6016:42;;6092:13;6079:9;:26;6075:405;;6126:17;6146:3;:11;;6158:9;6146:22;;;;;;;;:::i;:::-;;;;;;;;;6126:42;;6300:9;6271:3;:11;;6283:13;6271:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;6385:23;;;:12;;;:23;;;;;:36;;;6075:405;6561:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6656:3;:12;;:19;6669:5;6656:19;;;;;;;;;;;6649:26;;;6699:4;6692:11;;;;;;;5584:1176;6743:5;6736:12;;;;;105809:1052;105895:16;;-1:-1:-1;;;;;105895:16:0;105926:31;105922:44;;105959:7;105809:1052::o;105922:44::-;106012:24;;106051:29;;106047:363;;106152:29;;-1:-1:-1;;;106152:29:0;;106175:4;106152:29;;;181:51:1;91179:42:0;;106097:11;;91179:42;;106152:14;;154:18:1;;106152:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106130:51;-1:-1:-1;106200:15:0;;106196:203;;106236:147;106276:17;106316:48;:11;106338:25;106316:21;:48::i;:::-;-1:-1:-1;;;;;106236:17:0;;;:147;:17;:147::i;:::-;106082:328;;106047:363;106456:24;;106495:29;;106491:363;;106596:29;;-1:-1:-1;;;106596:29:0;;106619:4;106596:29;;;181:51:1;91083:42:0;;106541:11;;91083:42;;106596:14;;154:18:1;;106596:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106574:51;-1:-1:-1;106644:15:0;;106640:203;;106680:147;106720:17;106760:48;:11;106782:25;106760:21;:48::i;106680:147::-;106526:328;;105856:1005;;;105809:1052::o;12138:158::-;12212:7;12263:22;12267:3;12279:5;12263:3;:22::i;113985:185::-;114059:7;114086:76;114140:21;;43500:4;114123:38;;;;:::i;:::-;114086:26;114102:9;114086:15;:26::i;113039:192::-;113113:7;113140:83;113202:20;;43500:4;113185:37;;;;:::i;23376:712::-;23526:12;23555:7;23551:530;;;-1:-1:-1;23586:10:0;23579:17;;23551:530;23700:17;;:21;23696:374;;23898:10;23892:17;23959:15;23946:10;23942:2;23938:19;23931:44;23696:374;24041:12;24034:20;;-1:-1:-1;;;24034:20:0;;;;;;;;:::i;114535:168::-;114610:7;114637:58;114665:9;;;;;;;;;-1:-1:-1;;;;;114665:9:0;-1:-1:-1;;;;;114665:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114637:17;;:27;:58::i;24765:211::-;24909:58;;-1:-1:-1;;;;;6786:32:1;;24909:58:0;;;6768:51:1;6835:18;;;6828:34;;;24882:86:0;;24902:5;;-1:-1:-1;;;24932:23:0;6741:18:1;;24909:58:0;6594:274:1;7531:120:0;7598:7;7625:3;:11;;7637:5;7625:18;;;;;;;;:::i;:::-;;;;;;;;;7618:25;;7531:120;;;;:::o;43811:122::-;43875:7;43924:1;43903:17;43391:4;43903:1;:17;:::i;-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;1076:131::-;-1:-1:-1;;;;;1151:31:1;;1141:42;;1131:70;;1197:1;1194;1187:12;1131:70;1076:131;:::o;1212:247::-;1271:6;1324:2;1312:9;1303:7;1299:23;1295:32;1292:52;;;1340:1;1337;1330:12;1292:52;1379:9;1366:23;1398:31;1423:5;1398:31;:::i;2094:180::-;2153:6;2206:2;2194:9;2185:7;2181:23;2177:32;2174:52;;;2222:1;2219;2212:12;2174:52;-1:-1:-1;2245:23:1;;2094:180;-1:-1:-1;2094:180:1:o;2731:658::-;2902:2;2954:21;;;3024:13;;2927:18;;;3046:22;;;2873:4;;2902:2;3125:15;;;;3099:2;3084:18;;;2873:4;3168:195;3182:6;3179:1;3176:13;3168:195;;;3247:13;;-1:-1:-1;;;;;3243:39:1;3231:52;;3338:15;;;;3303:12;;;;3279:1;3197:9;3168:195;;;-1:-1:-1;3380:3:1;;2731:658;-1:-1:-1;;;;;;2731:658:1:o;3673:277::-;3740:6;3793:2;3781:9;3772:7;3768:23;3764:32;3761:52;;;3809:1;3806;3799:12;3761:52;3841:9;3835:16;3894:5;3887:13;3880:21;3873:5;3870:32;3860:60;;3916:1;3913;3906:12;3955:184;4025:6;4078:2;4066:9;4057:7;4053:23;4049:32;4046:52;;;4094:1;4091;4084:12;4046:52;-1:-1:-1;4117:16:1;;3955:184;-1:-1:-1;3955:184:1:o;4144:127::-;4205:10;4200:3;4196:20;4193:1;4186:31;4236:4;4233:1;4226:15;4260:4;4257:1;4250:15;4276:168;4316:7;4382:1;4378;4374:6;4370:14;4367:1;4364:21;4359:1;4352:9;4345:17;4341:45;4338:71;;;4389:18;;:::i;:::-;-1:-1:-1;4429:9:1;;4276:168::o;4449:127::-;4510:10;4505:3;4501:20;4498:1;4491:31;4541:4;4538:1;4531:15;4565:4;4562:1;4555:15;4581:217;4621:1;4647;4637:132;;4691:10;4686:3;4682:20;4679:1;4672:31;4726:4;4723:1;4716:15;4754:4;4751:1;4744:15;4637:132;-1:-1:-1;4783:9:1;;4581:217::o;4803:125::-;4843:4;4871:1;4868;4865:8;4862:34;;;4876:18;;:::i;:::-;-1:-1:-1;4913:9:1;;4803:125::o;5291:128::-;5331:3;5362:1;5358:6;5355:1;5352:13;5349:39;;;5368:18;;:::i;:::-;-1:-1:-1;5404:9:1;;5291:128::o;5424:251::-;5494:6;5547:2;5535:9;5526:7;5522:23;5518:32;5515:52;;;5563:1;5560;5553:12;5515:52;5595:9;5589:16;5614:31;5639:5;5614:31;:::i;7346:127::-;7407:10;7402:3;7398:20;7395:1;7388:31;7438:4;7435:1;7428:15;7462:4;7459:1;7452:15;7478:565;7686:2;7671:18;;7675:9;7766:6;7644:4;7800:194;7814:4;7811:1;7808:11;7800:194;;;7873:13;;7861:26;;7910:4;7934:12;;;;7969:15;;;;7834:1;7827:9;7800:194;;;7804:3;;;8030:6;8025:2;8014:9;8010:18;8003:34;7478:565;;;;;:::o;8386:127::-;8447:10;8442:3;8438:20;8435:1;8428:31;8478:4;8475:1;8468:15;8502:4;8499:1;8492:15;10074:274;10203:3;10241:6;10235:13;10257:53;10303:6;10298:3;10291:4;10283:6;10279:17;10257:53;:::i;:::-;10326:16;;;;;10074:274;-1:-1:-1;;10074:274:1:o;10353:127::-;10414:10;10409:3;10405:20;10402:1;10395:31;10445:4;10442:1;10435:15;10469:4;10466:1;10459:15
Swarm Source
ipfs://edb1f145197cf15b7091420f3d77d9c5e33ba3c6c5339bb44340e7c8fc29364c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $3,922.78 | 0.0105 | $41.23 |
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.